How to implement different behavior when the user clicks on different views in a ListView?
I a new to Android development, so this is kind of a basic question.
I would like to implement the same behavior as in the Contacts app. You have a ListView with a series of Contacts | phone icons. There you have one behavior when you click on the contact name, and another behavior when you click on the phone icon.
Here is my code. Any help is much appreciated.
In summary, what is wrong with the approach
switch (v.getId()) { case R.id.imageButtonAction:
Activity Class
public class CompaniesActivity extends Activity {
MyApp app;
ListView listCompanies;
Cursor cu开发者_JS百科rsor;
// Adapter and its corresponding FROM and TO statements. The number and sequence of the arguments must match in FROM / TO arguments.
SimpleCursorAdapter adapter;
static final String[] FROM = { MenuNavigationData.C_COMPANY, MenuNavigationData.C_DESCRIPTION};
static final int[] TO = { R.id.textCompany, R.id.textDescription }; //
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.companies);
//Gets a reference to the application
app = (MyApp) getApplication();
// Find your views
listCompanies = (ListView) findViewById(R.id.listCompanies);
addButton = (Button) findViewById(R.id.buttonAdd);
// Add actions to user interaction
listCompanies.setOnItemClickListener(new OnItemClickListener() {
@Override
**public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
switch (v.getId()) {
case R.id.imageButtonAction:
startActivity(new Intent(app, InstructionsActivity.class));
break;
default:
int i = adapter.getItemViewType(position);
startActivity(new Intent(app, EditMenuNavigationActivity.class));
break;
}**
}
});
}
Activity xml
<!-- Companies ListView-->
<ListView android:id="@+id/listView1" android:layout_height="wrap_content" android:layout_width="match_parent"></ListView>
<ListView
android:id="@+id/listCompanies"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1"
android:background="#5555"/>
</LinearLayout>
Row xml
android:background="#ffff"
android:padding="6dip">
<!-- Company TextView -->
<TextView
android:id="@+id/textCompany"
android:text="TIM"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:singleLine="true"
android:ellipsize="marquee"
android:textColor="#c000"
android:textStyle="bold"
android:textSize="25sp"/>
<!-- Description TextView -->
<TextView
android:id="@+id/textDescription"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_below="@id/textCompany"
android:layout_alignWithParentIfMissing="true"
android:layout_alignParentLeft="true"
android:singleLine="true"
android:ellipsize="marquee"
android:textColor="#c000"></TextView>
<!-- Action ImageView -->
<ImageView
android:id="@+id/imageButtonAction"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_gravity="right"
android:background="@drawable/icon"/>
</RelativeLayout>
Your onItemClick() callback receives both the specific view as well as its position (0-based), each of these can help you decide which view was clicked. The position is an index into the items you've added, and for more complicated scenarios you can view.setTag(Object o), and use getTag() to retrieve it from your callback.
New much better approach to solve this issue elegantly, and with less code!!!
With the following modifications, the User interface is much more responsive, no more double-clicking issues. :)
Much, much less code that simply works!
Modifications to Row xml
Insert a Linear layout to wrap both the In this Linear layout, insert a tag named android:onClick="editCompanyClick" This is the click handler that will be called in the Activity.
Insert a Linear layout to wrap the In this Linear layout, insert a tag named android:onClick="dialClick" This is the click handler that will be called in the Activity.
Modifications to Activity class
Remove the previous code
listCompanies.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView arg0, View v, int position, long id) {
TextView company = (TextView) v.findViewById(R.id.textCompany);
ImageView dial = (ImageView) v.findViewById(R.id.imageButtonDTMFDial);
company.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(app, EditMenuNavigationActivity.class));
}
});
dial.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(app, InstructionsActivity.class));
}
});
}
Insert the code
public void dialClick(View v) {
startActivity(new Intent(app, InstructionsActivity.class));
}
public void editCompanyClick(View v) {
startActivity(new Intent(app, EditMenuNavigationActivity.class));
record
}
Row xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip" android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/linearLayout1"
android:orientation="vertical"
android:onClick="editCompanyClick"
android:layout_weight="1">
<!-- Company TextView -->
<TextView android:singleLine="true" android:text="TIM" android:id="@+id/textCompany" android:ellipsize="marquee" android:layout_height="wrap_content" style="@android:style/TextAppearance.Medium" android:layout_width="match_parent" android:gravity="top"></TextView>
<!-- Description TextView -->
<TextView android:singleLine="true" android:text="Chamar atendente" android:id="@+id/textDescription" android:ellipsize="marquee" android:layout_height="wrap_content" style="@android:style/TextAppearance.Small" android:layout_width="match_parent" android:gravity="bottom"></TextView>
</LinearLayout>
<LinearLayout
android:layout_height="match_parent"
android:id="@+id/linearLayout2"
android:onClick="dialClick"
android:layout_width="wrap_content" android:layout_gravity="right">
<!-- DTMFDial ImageView -->
<ImageView android:layout_height="wrap_content" android:background="@drawable/icon" android:id="@+id/imageButtonDTMFDial" android:layout_gravity="right" android:layout_width="wrap_content"></ImageView>
</LinearLayout>
</LinearLayout>
I finally found a solution. This solves the issue. But adds another one. As expected, the ListView now behaves differently when the user clicks on different views(either TextView or ImageView). But it seems unresponsive. I have to "double-click" in order to trigger either the company.setOnClick or dial.setOnClick. Any suggestions?
// Add actions to user interaction
listCompanies.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
TextView company = (TextView) v.findViewById(R.id.textCompany);
ImageView dial = (ImageView) v.findViewById(R.id.imageButtonDTMFDial);
company.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(app, EditMenuNavigationActivity.class));
}
});
dial.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(app, InstructionsActivity.class));
}
});
}
精彩评论