Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
201 views
in Technique[技术] by (71.8m points)

Styling item Views in Android ListView

I can not figure out what going wrong with my ListView, because it is too small. I want bigger items like default list views on Android.

SelectContactActivity

public class SelectContactActivity extends Activity {

private ArrayList<Contact> listContacts = new ArrayList<Contact>();

private ArrayList<SongInfo> listSong = new ArrayList<SongInfo>();
private ListContactsAdapter adapter;
private Util util = new Util();
private ListView list;
private EditText txt_search;
private ArrayList<Contact> listSearch;

private Handler guiThread;

private Runnable updateTask;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.setContentView(R.layout.mycontacts);

list = (ListView)findViewById(R.id.list);
txt_search = (EditText)findViewById(R.id.txt_search);

final int position = this.getIntent().getIntExtra("position", 0);

listSong = util.getAllSong(this);

listContacts = util.getAllContact(this);

Log.i("LOG", "Size: " + listContacts.size());

adapter = new ListContactsAdapter(this,   android.R.layout.simple_list_item_1, listContacts);
list.setAdapter(adapter);
list.setTextFilterEnabled(true);

list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
util.assignRingtoneToContact(SelectContactActivity.this,
listSong.get(position), listContacts.get(arg2));
Toast.makeText(
SelectContactActivity.this,
"Ringtone set successfully",
Toast.LENGTH_LONG).show();
finish();
}
});

innitThread();

txt_search.addTextChangedListener(new TextWatcher() {

@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
queueUpdate(500);
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {

}

@Override
public void afterTextChanged(Editable s) {

}
});

}

private void queueUpdate(long delayMillisecond) {
guiThread.removeCallbacks(updateTask);
// update data if no change in textSearch after time config
// timer by = milliseconds
guiThread.postDelayed(updateTask, delayMillisecond);
}

private void innitThread() {
guiThread = new Handler();
updateTask = new Runnable() {

@Override
public void run() {

String word = txt_search.getText().toString().trim();
if (word.equalsIgnoreCase("")) {
// if not change set listView first
list.setAdapter(new  ListContactsAdapter(SelectContactActivity.this,
android.R.layout.simple_list_item_1, listContacts));
} else
// if txtSearch not null
{

// get data from webservice
getDataByKeywords(word);
// Show on list
listSearch = new ArrayList<Contact>();

// get data from webservice
listSearch = getDataByKeywords(word);

list.setAdapter(new ListContactsAdapter(SelectContactActivity.this,  android.R.layout.simple_list_item_1, listSearch));
adapter.notifyDataSetChanged();
}

}
};
}

public ArrayList<Contact> getDataByKeywords(String keyword) {
listSearch = new ArrayList<Contact>();
keyword = keyword.toUpperCase();
for (int i = 0; i < listContacts.size(); i++) {
String contain = listContacts.get(i).getName().toUpperCase();
if (contain.contains(keyword)) {
listSearch.add(listContacts.get(i));
}
}
return listSearch;
}

}

ListContactsAdapter

public class ListContactsAdapter extends ArrayAdapter<Contact>{

private ArrayList<Contact> contacts;
private Context context;

public ListContactsAdapter(Context context, int textViewResourceId,
ArrayList<Contact> objects) {
super(context, textViewResourceId, objects);
this.context = context;
this.contacts = objects;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView!=null){
convertView.setBackgroundResource(R.drawable.list_selector);
}

TextView textView = getGenericView();
textView.setBackgroundResource(R.drawable.list_selector);
textView.setText(contacts.get(position).getName());
return textView;
}

public TextView getGenericView() {
// Layout parameters for the ExpandableListView
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, 70);

TextView textView = new TextView(context);
textView.setLayoutParams(lp);
// Center the text vertically
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
// Set the text starting position
textView.setPadding(16, 0, 0, 0);
textView.setTextSize(18);
textView.setShadowLayer(1, 1, 1, Color.BLACK);
textView.setTextColor(0xffeeeeee);
return textView;
}

}

mycontacts.xml

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

<RelativeLayout
android:id="@id/relativeLayoutSearch"
android:layout_width="fill_parent"
android:layout_height="55dp"
android:gravity="center_vertical"
android:paddingLeft="12dp"
android:paddingRight="12dp" >

<EditText
android:id="@id/txt_search"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:background="@drawable/search_bar"
android:hint="@string/hint_apps_search"
android:paddingBottom="12dp"
android:paddingLeft="45.0dip"
android:paddingRight="14dp"
android:paddingTop="12dp"
android:singleLine="true"
android:textSize="15.0sp" />

<Button
android:id="@id/button2"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/zoomicon" />

</RelativeLayout>

<ListView
android:id="@id/list"
style="@style/ContactList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/relativeLayoutSearch"
android:cacheColorHint="#e0000000" />
</RelativeLayout>

styles.xml

    <style name="ContactList">
    <!-- <item name="android:background">@color/listbg</item> -->
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">fill_parent</item>
    <item name="android:cacheColorHint">#e0000000</item>
    <item name="android:divider">@color/listdiv</item>
    <item name="android:dividerHeight">1.0dip</item>
    </style>

This is my code for contact list, and here is a screenshot how this looks, but I want bigger items on list. Any suggestions?

Current listview:

Current listview

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I would start smaller, by revisiting your adapter. The ListView itself is very simple - in your activity layout, you set your ListView to be match_parent for both width and height.


The adapter is the component which creates each row, which in ListAdapter, is initiated by the getView() method.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView != null) {
        convertView.setBackgroundResource(R.drawable.list_selector);
    }

    TextView textView = getGenericView();
    textView.setBackgroundResource(R.drawable.list_selector);
    textView.setText(contacts.get(position).getName());
    return textView;
}

Note what you're doing here is incorrect; you do something to convertView but then you ignore it, and just make a new View. The pattern is more like:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View rowView = convertView;
    if (rowView == null) {
        rowView = // create a new View that represents your row
    }
    // bind the data to rowView, then return it
    return rowView;
}

which in your case might be:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    TextView rowView = (TextView) convertView;
    if (rowView == null) {
        rowView = getGenericView();
        rowView.setBackgroundResource(R.drawable.list_selector);
    }
    rowView.setText(contacts.get(position).getName());
    return rowView;
}

See, you only need to create rowView if it's null. Also, the background only needs to be set once (and this can be done in XML if you want).


With creating the row View, I'd recommend starting by inflating a layout that contains a single TextView as the only element.

view_item_contact.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="wrap_content" />

then your getGenericView() can be renamed to createContactRowView():

private TextView createContactRowView(ViewGroup parent) {
    LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
    return ((TextView) layoutInflater.inflate(R.layout.view_item_contact, parent, false));
}

From there, you can start to style your row in view_item_contact.xml by adding padding, setting a minimum height, centering the text vertically by applying gravity, etc.

view_item_contact.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:minHeight="48dp"
  android:gravity="center_vertical"
  android:paddingLeft="16dp"
  android:paddingRight="16dp"
  android:background="@drawable/list_selector" />

In almost all cases, I would avoid creating Views programmatically - always inflate them from XML, so you can separate styles and layout from your logic.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...