Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Android

Writing Android GUI using Python (6:layout)

0.00/5 (No votes)
30 May 2012CPOL1 min read 28.1K  
How to write Android GUI using Python (6:layout)

Introduction

Wrapandroid 0.8.5 is uploaded, programmers can download it from here. In this version, a method is presented which can be used to unzip files to directory on sdcard or package path. If path does not exist, it will be created automatically. The method name is “unzipAssetFile”. Programmers can call it through activity object. The prototype of the functions is “boolean unzipAssetFile(StarObjectClass self,String zipFileName, String outputDirectory,Boolean OverWriteFlag)”. The zipFileName is located on assets directory of the project. From version 0.8.5, layout is supported. You can use “findViewById” or “inflate” function to retrieve widgets defined in XML file. The two functions are a little different from the Android version. “ClassName” is added as an input parameter; because program does not know which class the widgets belong to. The classname is widget name with a “Class” postfix. For example, LinearLayout should be used as LinearLayoutClass.

First Example

This example is shown how to get widgets defined in layout.

layout file main.xml, which includes a linearlayout, textview and a button

XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/widget73"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/widget45"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    <Button
        android:id="@+id/widget74"
        android:layout_width="220dp"
        android:layout_height="48dp"
        android:text="thank for your use"
        android:typeface="serif"
        android:textStyle="bold"
        android:textColor="#ffff0000"
        android:layout_x="284dp"
        android:layout_y="220dp"
        android:textSize="16dp"
    />
</LinearLayout>

Python Code

Python
SrvGroup = libstarpy._GetSrvGroup()
Service = SrvGroup._GetService("","")
#--get activity
StarActivity = Service.ActivityClass.getCurrent();
#--get textview defined in layout
MyText = StarActivity.findViewById("TextViewClass",StarActivity.getResource("id/widget45"));
#--set text
MyText.setText("from layout");
#--get button defined in layout
MyButton = StarActivity.findViewById("ButtonClass",StarActivity.getResource("id/widget74"));
#--set onClick function of the button
def MyButton_onClick(self, Ev) :
    Service.ToastClass._New().makeText("Button is click", 0).show();
MyButton.onClick = MyButton_onClick;
MyButton.setOnClickListener();
#--set text
MyButton.setText("click me");
#--get linearlayout defined in layout
MyLinearLayout = StarActivity.findViewById
("LinearLayoutClass",StarActivity.getResource("id/widget73"));
#--create a button dynamically
MyDynaButton = Service.ButtonClass._New(MyLinearLayout);
#--set onClick function of the button
def MyDynaButton_onClick(self, Ev) :
    Service.ToastClass._New().makeText("Button is click", 0).show();
MyDynaButton.onClick = MyDynaButton_onClick;
MyDynaButton.setOnClickListener();
#--set text
MyDynaButton.setText("created dynamically");
#--set layout parameter
MyDynaButton.setLinearLayoutParams(100,50);

Screenshot

Example (view holder)

Viewholder is often talked about and used in list view to speed up scroll process. Using Python, we can also use a method similar to the view holder. For python is a dynamic language, this is easy to realize.

Layout file, which will be used in list view

XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">


    <ImageView android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5px"/>
    <LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="22px" />
<TextView android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="13px" />
    </LinearLayout>

    <Button android:id="@+id/view_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="more"
android:layout_gravity="bottom|right" />
</LinearLayout>

Python Code

Python
SrvGroup = libstarpy._GetSrvGroup()
Service = SrvGroup._GetService("","")
#--get activity
StarActivity = Service.ActivityClass.getCurrent();
#--create AbsoluteLayout
MyLayout = Service.AbsoluteLayoutClass._New(StarActivity);
#--create an inflater, which will be used to inflate the layout file.
mInflater = Service.LayoutInflaterClass._New();
#--create adapter for list view
MyAdapter = Service.BaseAdapterClass._New();

#--override getCount function
def MyAdapter_getCount(self) :
    return 20;
MyAdapter.getCount = MyAdapter_getCount;  

#--override getItem function
def MyAdapter_getItem(self,position) :
    return position;
MyAdapter.getItem = MyAdapter_getItem;  

#--override getItemId function
def MyAdapter_getItemId(self,position)  :
    return position;
MyAdapter.getItemId = MyAdapter_getItemId;
#--override getView function
def MyAdapter_getView(self,position,convertView,parent) :
    global Service,mInflater,StarActivity;
    if(convertView == None) :
        #--if input convertView is empty, then we inflate from layout
        #--define holder for python, here we use list
        holder={};
        convertView = mInflater.inflate("LinearLayoutClass",
        StarActivity.getResource("layout/vlist2"),None);
      #--get ImageView from layout
        holder["img"] = convertView.findViewById
        ("ImageViewClass",StarActivity.getResource("id/img"));
        #--get TextView from layout
        holder["title"] = convertView.findViewById
        ("TextViewClass",StarActivity.getResource("id/title"));
        #--get TextView from layout
        holder["info"] = convertView.findViewById
        ("TextViewClass",StarActivity.getResource("id/info"));
        #--get Button from layout
        holder["viewBtn"] = convertView.findViewById
        ("ButtonClass",StarActivity.getResource("id/view_btn"));
    #--assign holder to convertView, here variable Tag is defined dynamically
        convertView.Tag = holder;
    #--call _SLockGC, hold convertView in python space.
        convertView._SLockGC();    
        
    else :
        #--if input convertView is not null, then we get holder from convertView
        holder = convertView.Tag;

    #--assign values for each widgets in the holder.
    if( position % 3 == 0 ) :
        holder["img"].setBackgroundResource(StarActivity.getResource("drawable/i1"));
        holder["title"].setText("G1");
        holder["info"].setText("google 1");
    elif( position % 3  == 1 ):
        holder["img"].setBackgroundResource(StarActivity.getResource("drawable/i2"));
        holder["title"].setText("G2");
        holder["info"].setText("google 2");
    elif( position % 3  == 2 ):
        holder["img"].setBackgroundResource(StarActivity.getResource("drawable/i3"));
        holder["title"].setText("G3");
        holder["info"].setText("google 3");
    #--set onClick event function for viewBtn.
    def holder_viewBtn_onClick(self, Ev) :
        Service.ToastClass._New().makeText("Button is click", 0).show();
    holder["viewBtn"].onClick = holder_viewBtn_onClick;
    holder["viewBtn"].setOnClickListener();
    return convertView;
MyAdapter.getView = MyAdapter_getView;
#--create a list view and assign adapter to it.
MyListView = Service.ListViewClass._New(MyLayout);
MyListView.setAbsoluteLayoutParams(Service.FILL_PARENT,Service.FILL_PARENT,0,0);
MyListView.setAdapter(MyAdapter);

Screenshot

The example can be downloaded from here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)