Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't click on items in ListView with custom adapter

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;
    }
like image 372
AndroidNoob Avatar asked Mar 12 '13 02:03

AndroidNoob


People also ask

How can you react to click events on an item of a ListView?

Place an empty linearlayout below the listview by setting an appropriate height to the listview. Place an onClick() method to that linear layout. That must do it. Save this answer.

What does an Adaptor do for a view like a ListView?

In Android, Adapter is a bridge between UI component and data source that helps us to fill data in UI component. It holds the data and send the data to an Adapter view then view can takes the data from the adapter view and shows the data on different views like as ListView, GridView, Spinner etc.

Is ListView deprecated?

Warning:` ListView is deprecated and will be removed in a future release.

How can you update a ListView dynamically?

This example demonstrates how do I dynamically update a ListView in android. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.


2 Answers

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">
like image 138
Mario Avatar answered Nov 07 '22 04:11

Mario


I usually put the click listener in the adapter itself:

@Override
      public View getView(int position, View convertView, ViewGroup parent) {

        OnClickListener yourClickListener = new OnClickListener() {
              public void onClick(View v) {
                //put your desired action here
                v.callOnClick();
              }
          };

    ...

    // then add the listener to your view
    tweetView.setOnClickListener(yourClickListener);
like image 1
TrippinBilly Avatar answered Nov 07 '22 03:11

TrippinBilly