Can't click on items in ListView with custom adapter
android, listview
Solution
Usually this happens because the items in your listview are in focus. Try adding
android:descendantFocusability="blocksDescendants"
in your custom listview row
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip"
android:orientation="vertical"
android:descendantFocusability="blocksDescendants">
Problem
I am trying to write an application which takes items from a database and populates rows within a ListView. I can't click on the items after tapping on the rows and the dpad won't go to any of the rows either. I am using a custom Adapter. Tweet.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="?android:attr/listPreferredItemHeight" android:padding="6dip" android:orientation="vertical"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/textUser" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:text="NAME"/> <TextView android:id="@+id/textDate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#333333" android:text="DATE" /> </LinearLayout> <TextView android:id="@+id/textTweet" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TWEET" /> </LinearLayout> ``` Activity_main.xml ``` <?xml version="1.0" encoding="UTF-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" tools:context=".MainActivity" > </ListView> ``` Oncreate Method ``` @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView view = (ListView) findViewById(R.id.listView); MyArrayAdapter theAdapter = new MyArrayAdapter(tweetDb,this); //setContentView(theAdapter.getView(0, null, null)); view.setAdapter(theAdapter); view.setOnItemClickListener( new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { //Tweet theTweet = (Tweet)parent.getAdapter().getItem(position); //saved.insert(theTweet); Toast.makeText(getApplicationContext(), "Saved", Toast.LENGTH_LONG).show(); Log.v("SCHEMA", "onItemClick fired!"); } } ); } ``` Adapter Class getView ``` @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater)context.getSystemService( Context.LAYOUT_INFLATER_SERVICE ); View tweetView = inflater.inflate(R.layout.tweet, null); TextView textTweet = (TextView) tweetView.findViewById(R.id.textTweet); textTweet.setText(items.get(position).getTweet()); textTweet = (TextView)tweetView.findViewById(R.id.textUser); textTweet.setText(items.get(position).getName()); textTweet = (TextView)tweetView.findViewById(R.id.textDate); textTweet.setText(textFormat.format(items.get(position).getCreated())); return tweetView; } ``` MyArrayAdapter Class ``` import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import android.content.Context; import android.database.Cursor; import android.database.DataSetObserver; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ListAdapter; import android.widget.TextView; import android.widget.Toast; public class MyArrayAdapter implements ListAdapter { private ArrayList<Tweet> items; private Context context; private SimpleDateFormat textFormat = new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy"); public MyArrayAdapter(TweetDbSource db, Context context) { items = new ArrayList<Tweet>(); this.context = context; Cursor cursor = db.getReadableDatabase().query("Tweet", null, null, null, null, null, null); while (!cursor.isLast()) { cursor.moveToNext(); items.add(new Tweet(cursor.getLong(0),cursor.getLong(1),cursor.getString(2),cursor.getString(3), cursor.getString(4),new Date(),cursor.getInt(6))); } } @Override public int getCount() { return items.size(); } @Override public Object getItem(int position) { return items.get(position); } @Override public long getItemId(int position) { return position; } @Override public int getItemViewType(int arg0) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater)context.getSystemService( Context.LAYOUT_INFLATER_SERVICE ); OnClickListener saveTweet = new OnClickListener() { public void onClick(View v) { Toast.makeText(v.getContext(), "Saved", Toast.LENGTH_LONG).show(); } }; View tweetView = inflater.inflate(R.layout.tweet, null); TextView textTweet = (TextView) tweetView.findViewById(R.id.textTweet); textTweet.setText(items.get(position).getTweet()); textTweet = (TextView)tweetView.findViewById(R.id.textUser); textTweet.setText(items.get(position).getName()); textTweet = (TextView)tweetView.findViewById(R.id.textDate); textTweet.setText(textFormat.format(items.get(position).getCreated())); return tweetView; } @Override public int getViewTypeCount() { // TODO Auto-generated method stub return 1; } @Override public boolean hasStableIds() { // TODO Auto-generated method stub return false; } @Override public boolean isEmpty() { // TODO Auto-generated method stub return items.size() == 0; } @Override public void registerDataSetObserver(DataSetObserver arg0) { // TODO Auto-generated method stub } @Override public void unregisterDataSetObserver(DataSetObserver arg0) { // TODO Auto-generated method stub } @Override public boolean areAllItemsEnabled() { // TODO Auto-generated method stub return false; } @Override public boolean isEnabled(int arg0) { // TODO Auto-generated method stub return false; } } ``` Toast or log is not working, that's how I can tell it's not working Updated getView Method ``` public View getView(int position, View convertView, ViewGroup parent) { OnClickListener SaveView = new OnClickListener() { @SuppressLint("NewApi") public void onClick(View v) { Toast.makeText(v.getContext(), "Saved", Toast.LENGTH_LONG).show(); v.callOnClick(); } }; LayoutInflater inflater = (LayoutInflater)context.getSystemService( Context.LAYOUT_INFLATER_SERVICE ); View tweetView = inflater.inflate(R.layout.tweet, null); TextView textTweet = (TextView) tweetView.findViewById(R.id.textTweet); textTweet.setText(items.get(position).getTweet()); textTweet = (TextView)tweetView.findViewById(R.id.textUser); textTweet.setText(items.get(position).getName()); textTweet = (TextView)tweetView.findViewById(R.id.textDate); textTweet.setText(textFormat.format(items.get(position).getCreated())); tweetView.setOnClickListener(SaveView); return tweetView; } ``` UPDATE The issue was solved and I figured it out :D I had to return true instead of false in these two methods within my adapter class! ``` @Override public boolean areAllItemsEnabled() { return true; } @Override public boolean isEnabled(int arg0) { return true; } ```