I liked the decision of Carlos Sessa from his book “50 Android hacks”.
my activity_favorites.xml is as follows:
<?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"> <ListView android:id="@+id/favContainer" android:layout_width="fill_parent" android:layout_height="fill_parent" android:choiceMode="singleChoice"/> </RelativeLayout>
My FavoritesActivity.java looks like this:
package com.myproject; import java.util.ArrayList; import com.myproject.R; import com.myproject.model.Package; import com.myproject.adapter.FavoritesPackageArrayAdapter; import com.myproject.utils.DatabaseHelper; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.Window; import android.widget.ListView; public class FavoritesActivity extends Activity { protected ListView list; protected String selectedPackage; protected ArrayList<Package> packages; protected FavoritesPackageArrayAdapter adapter; private DatabaseHelper db = new DatabaseHelper(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_favorites); packages = db.getPackages(); adapter = new FavoritesPackageArrayAdapter(this, -1, packages); list = (ListView) findViewById(R.id.favContainer); list.setAdapter(adapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } public void onSelect(View view) { int pos = list.getCheckedItemPosition(); if(ListView.INVALID_POSITION != pos) selectedPackage = packages.get(pos).getId(); } }
My ListView adapter (FavoritesPackageArrayAdapter.java) is pretty simple:
package com.myproject.adapter; import java.util.List; import com.myproject.model.Package; import com.myproject.view.PackageView; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; public class FavoritesPackageArrayAdapter extends ArrayAdapter<Package> { public FavoritesPackageArrayAdapter(Context context, int resource, List<Package> objects) { super(context, resource, objects); } @Override public View getView(int position, View convertView, ViewGroup parent) { if(convertView == null) convertView = new PackageView(getContext()); Package pack = getItem(position); PackageView packView = (PackageView) convertView; packView.setPackage(pack); return convertView; } }
To check list items, your view must implement the Checkable interface. My PackageView.java looks like this:
package com.myproject.view; import java.util.ArrayList; import com.myproject.R; import com.myproject.model.Package; import com.myproject.model.PackageEvent; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.widget.Checkable; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.CheckBox; public class PackageView extends LinearLayout implements Checkable { private View v; private TextView tv0; private TextView tv1; private TextView tv2; private TextView tv3; private CheckBox testCheckBox; public PackageView(Context context) { super(context); LayoutInflater inflater = LayoutInflater.from(context); v = inflater.inflate(R.layout.favorites_package, this, true); tv0 = (TextView) v.findViewById(R.id.favPackageId); tv1 = (TextView) v.findViewById(R.id.favEventDate); tv2 = (TextView) v.findViewById(R.id.favEventAddres); tv3 = (TextView) v.findViewById(R.id.favEventState);
And finally, the xml layout of each list item (favorites_package.xml):
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/favPackageId" android:layout_width="match_parent" android:layout_height="wrap_content"/> <LinearLayout android:id="@+id/favTimeDateContainer" android:layout_width="match_parent" android:layout_height="wrap_content" android:weightSum="1"> <TextView android:id="@+id/favEventDate" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="0.5"/> <TextView android:id="@+id/favEventAddres" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.5"/> </LinearLayout> <TextView android:id="@+id/favEventState" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
If you want to have the actual flag in your layout, then the xml should look something like this:
<CheckBox android:id="@+id/checkBoxId" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:focusable="false" android:focusableInTouchMode="false"/>
If you leave the checkbox interactively, you can check it only by clicking on the checkbox. Also, do not make your layout clickable, for some reason it does not work with the Checkable interface.