50

The below is my testing code to create the list view, the list view display successfully, however, there is error in click event. I would like to create an intent to send a hardcode message to an new activity. However, it show error for the line

Intent intent = new Intent(context, SendMessage.class);

So , the problem is , what should I provide for this class?

Also , instead of hard code the output message, how to capture the data in list view row and pass to the new activity? e.g. BBB,AAA,R.drawable.tab1_hdpi for the first row.

Thanks.

public class MainActivity extends Activity {
    public final static String EXTRA_MESSAGE = "com.example.ListViewTest.MESSAGE";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ArrayList<ListEntry> members = new ArrayList<ListEntry>(); 
        members.add(new ListEntry("BBB","AAA",R.drawable.tab1_hdpi));
        members.add(new ListEntry("ccc","ddd",R.drawable.tab2_hdpi));
        members.add(new ListEntry("assa","cxv",R.drawable.tab3_hdpi));
        members.add(new ListEntry("BcxsadvBB","AcxdxvAA"));
        members.add(new ListEntry("BcxvadsBB","AcxzvAA"));
        members.add(new ListEntry("BcxvBB","AcxvAA"));
        members.add(new ListEntry("BvBB","AcxsvAA"));
        members.add(new ListEntry("BcxvBB","AcxsvzAA"));
        members.add(new ListEntry("Bcxadv","AcsxvAA"));
        members.add(new ListEntry("BcxcxB","AcxsvAA"));
        ListView lv = (ListView)findViewById(R.id.listView1);
        Log.i("testTag","before start adapter");
        StringArrayAdapter ad = new StringArrayAdapter (members,this);
        Log.i("testTag","after start adapter");
        Log.i("testTag","set adapter");
        lv.setAdapter(ad);
        lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                Intent intent = new Intent(context, SendMessage.class);
                String message = "abc";
                intent.putExtra(EXTRA_MESSAGE, message);
                startActivity(intent);
            }
        });
    }
Bishan
  • 15,211
  • 52
  • 164
  • 258
user782104
  • 13,233
  • 55
  • 172
  • 312

6 Answers6

113

I can not see where do you declare context. For the purpose of the intent creation you can use MainActivity.this

 lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                Intent intent = new Intent(MainActivity.this, SendMessage.class);
                String message = "abc";
                intent.putExtra(EXTRA_MESSAGE, message);
                startActivity(intent);
            }
        });

To retrieve the object upon you have clicked you can use the AdapterView:

ListEntry entry = (ListEntry) parent.getItemAtPosition(position);
Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • Thanks, what does context means anyway? – user782104 Jul 25 '13 at 07:33
  • That means, what is the first parameter in Intent class actually represent? What does MainActivity.this means? thanks – user782104 Jul 25 '13 at 07:38
  • 2
    from the documentation `This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents`. It has the information android needs to start your SendMessage activity – Blackbelt Jul 25 '13 at 07:39
  • Thanks, also why Unable to find explicit activity class {com.example.listviewtest/com.example.listviewtest.ItemDetails}; have you declared this activity in your AndroidManifest.xml? – user782104 Jul 25 '13 at 07:44
  • I have created public class ItemDetails extends Activity already – user782104 Jul 25 '13 at 07:45
  • you have to declare ItemDetails inside AndroidManifest.xml. All the Activities have to been declared inside AndroidManifest.xml – Blackbelt Jul 25 '13 at 07:47
  • Fixed. Last question... If the entry object (ListEntry) have 3 item ? two string and one integer (a photo stored), How to expose it and pass to new activity (is it necessary to)? – user782104 Jul 25 '13 at 07:53
  • if ListEntry is serializable you can pass the whole object otherwise you have to pass all the fields you need through the itent (you already to with EXTRA_MESSAGE). Be aware that it worky like an HashMap . For every field you have to provide a different key – Blackbelt Jul 25 '13 at 07:56
  • Wouldn't it make more sense to pass the Object at Position to the destination activity? – peterb Apr 17 '16 at 12:30
  • @peterb it could. it depends on the use case. `ListEntry`, in this case, should be parcelable/serializable to be passed to the new activity – Blackbelt Apr 17 '16 at 12:51
  • @Blackbelt can you give me class ListEntry? – TapanHP Dec 13 '16 at 05:57
  • @TapanHP ListEntry isn't part of the framework, it was OP's model class – Blackbelt Dec 13 '16 at 08:01
  • Okay got it @Blackbelt – TapanHP Dec 13 '16 at 08:12
  • thanx a lot! it's very helpful – Serg Shapoval Apr 10 '17 at 10:38
13

ListView has the Item click listener callback. You should set the onItemClickListener in the ListView. Callback contains AdapterView and position as parameter. Which can give you the ListEntry.

lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                ListEntry entry= (ListEntry) parent.getAdapter().getItem(position);
                Intent intent = new Intent(MainActivity.this, SendMessage.class);
                String message = entry.getMessage();
                intent.putExtra(EXTRA_MESSAGE, message);
                startActivity(intent);
            }
        });
Kapil Vats
  • 5,485
  • 1
  • 27
  • 30
  • 1
    Thanks. If the entry object have 3 item ? two string and one integer (a photo stored), How to expose it and pass to new activity (is it necessary to)? – user782104 Jul 25 '13 at 07:49
  • You can Implement Parceble or Serializable in ListEntry and can pass the whole object to the your new activity. – Kapil Vats Oct 24 '15 at 18:59
6

Error is coming in your code from this statement as you said

Intent intent = new Intent(context, SendMessage.class);

This is due to you are providing context of OnItemClickListener anonymous class into the Intent constructor but according to constructor of Intent

android.content.Intent.Intent(Context packageContext, Class<?> cls)

You have to provide context of you activity in which you are using intent that is the MainActivity class context. so your statement which is giving error will be converted to

Intent intent = new Intent(MainActivity.this, SendMessage.class);

Also for sending your message from this MainActivity to SendMessage class please see below code

lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                ListEntry entry= (ListEntry) parent.getAdapter().getItem(position);
                Intent intent = new Intent(MainActivity.this, SendMessage.class);
                intent.putExtra(EXTRA_MESSAGE, entry.getMessage());
                startActivity(intent);
            }
        });

Please let me know if this helps you

EDIT:- If you are finding some issue to get the value of list do one thing declear your array list

ArrayList<ListEntry> members = new ArrayList<ListEntry>();

globally i.e. before oncreate and change your listener as below

 lv.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position,
                        long id) {
                    Intent intent = new Intent(MainActivity.this, SendMessage.class);
                    intent.putExtra(EXTRA_MESSAGE, members.get(position));
                    startActivity(intent);
                }
            });

So your whole code will look as

public class MainActivity extends Activity {
    public final static String EXTRA_MESSAGE = "com.example.ListViewTest.MESSAGE";
ArrayList<ListEntry> members = new ArrayList<ListEntry>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        members.add(new ListEntry("BBB","AAA",R.drawable.tab1_hdpi));
        members.add(new ListEntry("ccc","ddd",R.drawable.tab2_hdpi));
        members.add(new ListEntry("assa","cxv",R.drawable.tab3_hdpi));
        members.add(new ListEntry("BcxsadvBB","AcxdxvAA"));
        members.add(new ListEntry("BcxvadsBB","AcxzvAA"));
        members.add(new ListEntry("BcxvBB","AcxvAA"));
        members.add(new ListEntry("BvBB","AcxsvAA"));
        members.add(new ListEntry("BcxvBB","AcxsvzAA"));
        members.add(new ListEntry("Bcxadv","AcsxvAA"));
        members.add(new ListEntry("BcxcxB","AcxsvAA"));
        ListView lv = (ListView)findViewById(R.id.listView1);
        Log.i("testTag","before start adapter");
        StringArrayAdapter ad = new StringArrayAdapter (members,this);
        Log.i("testTag","after start adapter");
        Log.i("testTag","set adapter");
        lv.setAdapter(ad);
        lv.setOnItemClickListener(new OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position,
                            long id) {
                        Intent intent = new Intent(MainActivity.this, SendMessage.class);
                        intent.putExtra(EXTRA_MESSAGE, members.get(position).getMessage());
                        startActivity(intent);
                    }
                });
    }

Where getMessage() will be a getter method specified in your ListEntry class which you are using to get message which was previously set.

Abhinav Singh Maurya
  • 3,313
  • 8
  • 33
  • 51
6

First, the class must implements the click listenener :

implements OnItemClickListener

Then set a listener to the ListView

yourList.setOnItemclickListener(this);

And finally, create the clic method:

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast.makeText(MainActivity.this, "You Clicked at ",   
 Toast.LENGTH_SHORT).show();
}
Avinash Garg
  • 1,374
  • 14
  • 18
2
    //get main activity
    final Activity main_activity=getActivity();

    //list view click listener
    final ListView listView = (ListView) inflatedView.findViewById(R.id.listView_id);
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String stringText;

            //in normal case
            stringText= ((TextView)view).getText().toString();                

            //in case if listview has separate item layout
            TextView textview=(TextView)view.findViewById(R.id.textview_id_of_listview_Item);
            stringText=textview.getText().toString();                

            //show selected
            Toast.makeText(main_activity, stringText, Toast.LENGTH_LONG).show();
        }
    });

    //populate listview
Rijul Sudhir
  • 2,064
  • 1
  • 15
  • 19
2

According to my test,

  1. implements OnItemClickListener -> works.

  2. setOnItemClickListener -> works.

  3. ListView is clickable by default (API 19)

The important thing is, "click" only works to TextView (if you choose simple_list_item_1.xml as item). That means if you provide text data for the ListView, "click" works when you click on text area. Click on empty area does not trigger "click event".