Dynamic List – Android Development Tip

When I was starting to recode Speech Timer for Android, I realised two things. One, the android tutorial in their website is too verbose for me. I need to read too many documents to get what I need. Second, the default Views of Android are not providing me what my application needs.

Well I have to say reading the introduction about how the Activity life cycle works is useful, and so is trying the Hello World and Hello Views tutorials. But besides that, I prefer to find the answer to my programming challenges from either stackoverflows.com or any other site which offers a question and answer mode. I find my productivity increases a lot. I mean, Google does present a pretty neat website to android development, but sometimes I am reading too many theory.

For this blog entry, I would like to discus about dynamic list generation. Android’s default implementation for ListView and ListActivity, are cumbersome for me. I cannot display it only as a part of a page, and I cannot load the content automatically if I use the XML showed in Android website’s tutorial. The tutorial only shows me that ListView is only applicable to a ListActivity, wherein the screen can only display a list, and the data for the list is expected to be static if I use the XML implementation.

For Speech Timer, I wanted to display two lists in a screen. The  first screen will be dynamic, it will show a list of contacts whose name matches a pattern. The second list will display a list of speech types.

Screen Shot 2012 09 24 at 9 35 32 PM

After some trial and error, I found the following code snippet suits me just well. The code below is to display the first list which is dynamic. It consists of several methods. The code to display the second list is simpler.

<!-- The XML part -->

			<EditText
			     android:id="@+id/orator"
			     android:layout_width="220dp"
			     android:layout_alignParentTop="true"
			     android:layout_marginTop="10dp"
				 android:layout_marginLeft="10dp"
			     android:layout_marginRight="10dp"
			     android:layout_toRightOf="@id/oratorLabel"
			     android:layout_height="wrap_content"/>
			<ScrollView android:id="@+id/scrollOrator"
				android:layout_width="fill_parent"
				android:layout_below="@id/orator"
				android:layout_marginTop="2dp"
				android:fadeScrollbars="false"
				android:layout_height="150dp">
					  <RelativeLayout
							  	  android:id="@+id/oratorSection"
							  	  android:orientation="vertical"
							      android:layout_width="fill_parent"
							      android:layout_height="fill_parent">
						</RelativeLayout>
			</ScrollView>

 

//The main onResume method

	 protected void onResume(){
    	 super.onResume();
    	 this.setContentView(R.layout.select_speech);
    	 final ArrayList<String> sourceCt = getContactList();
    	 linOrator = (RelativeLayout)findViewById(R.id.oratorSection);
    	 orator = (TextView)findViewById(R.id.orator);
    	 if(sourceCt!=null&&sourceCt.size()>0){
    		 orator.setOnKeyListener(new OnKeyListener(){
	    		 @Override
				 public boolean onKey(View v, int keyCode, KeyEvent event) {
						TextView tv = (TextView)v;
						ArrayList<String> fl = getFilterList(tv.getText().toString().trim(),sourceCt);
						displayFilteredContacts(fl);
						return false;
					}
		    	 });
    	 }
    }

//Filtering the list
private ArrayList<String> getFilterList(String searchStr,ArrayList<String> source){
     //Only basic logic here, so no need to explain. You can do it.
}

//Getting the names from the contacts list
private ArrayList <String> getContactList(){
   ArrayList<String> contactData=new ArrayList<String>();
   Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
while (cursor.moveToNext()) {
try{
String name=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contactData.add(name);
}catch(Exception e){
Toast.makeText(SelectSpeechActivity.this, "Failed getting contacts data.Please contact Basil Salad support", Toast.LENGTH_SHORT).show();
}
}
return contactData;
}

//Run this code if the user clicks on a row from the dynamic list
private void selectOratorName(TextView t){
      orator.setText(t.getText());
      linOrator.removeAllViews();
}

//The code to display the dynamic list

private void displayFilteredContacts(ArrayList<String> filtered){
//In the beginning, always clear the list
linOrator.removeAllViews();

//We will create each row dynamically
int size = filtered.size();
for(int i=0;i<size;i++){
RelativeLayout innerLinLay = new RelativeLayout(this);
innerLinLay.setId(22222*(i+1));
RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.bottomMargin=3;
if(i==0){
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
}else{
params.addRule(RelativeLayout.BELOW, 22222*i);
}
innerLinLay.setLayoutParams(params);
innerLinLay.setOnClickListener(new OnClickListener(){
           @Override
           public void onClick(View v) {
               TextView t = (TextView)r.getChildAt(0);
               selectOratorName(t);
           }
});
TextView tv = new TextView(this);
tv.setText(filtered.get(i));
tv.setTextColor(Color.BLACK);
tv.setClickable(true);
tv.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
               selectOratorName(v);
            }
});
RelativeLayout.LayoutParams tv1params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,           ViewGroup.LayoutParams.WRAP_CONTENT);
tv1params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
tv.setGravity(Gravity.CENTER_VERTICAL);
tv.setLayoutParams(tv1params);
tv.setId(222+i);
innerLinLay.addView(tv);

/** The code to display the line, no need to explain it here */
linOrator.addView(innerLinLay);
}
//Always redraw the list at the end
linOrator.refreshDrawableState();
}


Avoid App Review rules by distributing outside the Mac App Store!


Get my FREE cheat sheets to help you distribute real macOS applications directly to power users.

* indicates required

When you subscribe you’ll also get programming tips, business advices, and career rants from the trenches about twice a month. I respect your e-mail privacy.

Avoid Delays and Rejections when Submitting Your App to The Store!


Follow my FREE cheat sheets to design, develop, or even amend your app to deserve its virtual shelf space in the App Store.

* indicates required

When you subscribe you’ll also get programming tips, business advices, and career rants from the trenches about twice a month. I respect your e-mail privacy.

0 thoughts on “Dynamic List – Android Development Tip

Leave a Reply