57

I have two fragments. The first with buttons inside, the other with a ListView inside (ListFragment).

I would like the first fragment (thanks to its buttons) to allow the user to browse the ListView which is in the second fragment.

So I want the ListView to be controlled by the first fragment with buttons.

I've no problem communicating between fragment (sending orders from 1st fragment to the 2nd), but I don't know how to tell my ListView to select (programmatically) a particular list item.

What kind of ListView should I use and how can I tell the ListView to Select/Highlight/Focus one of its items?

I am in touch mode as the user presses on the buttons of the 1st fragment.

Should I use setFocusableInTouchMode(true) or setChoiceMode(ListView.CHOICE_MODE_SINGLE) or something else?

JDJ
  • 4,298
  • 3
  • 25
  • 44
Jecimi
  • 4,113
  • 7
  • 31
  • 40
  • i am making a chating application and make a fcm push Notification . I want when FCM notification come goes to chat room but when i am set a link to chat room application will be crashed please help me how can i do this . – Ashish Shahi Apr 20 '17 at 12:34
  • Another wise You have Give me idea without click on list view item automatically select list view whose person those value is passing through string value. It is too much urgent Please help me. Thanks In Advance. – Ashish Shahi Apr 20 '17 at 12:36

9 Answers9

144

This is for everyone trying to :

-Select programmatically an Item in a ListView

-Making this Item stay Highlighted

I'm working on Android ICS, I don't know if it works for all levels Api.

First create a listview (or get it if you're already in a listActivity/listFragment)

Then set the choice mode of your listview to single with :Mylistview.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

Then select programmatically your item with :Mylistview.setItemChecked(position, true); (position being an integer indicating the rank of the item to select)

Now your item is actually selected but you might see absolutely nothing because there's no visual feedback of the selection. Now you have two option : you can either use a prebuilt listview or your custom listview.

1) If you want a prebuilt listview, give a try to simple_list_item_activated_1, simple_list_item_checked , simple_list_item_single_choice, etc...

You can set up your listview like this for e.g : setListAdapter(new ArrayAdapter<String>(this, R.layout.simple_list_item_activated_1, data))

following which prebuilt listview you chose you'll see now that when selected you have a checkbox ticked or the backgound color changed , etc...

2) If you use a custom listview then you'll define a custom layout that will be used in each item. In this XML layout you will attribute a selector for each part view in you row which need to be changed when selected.

Let's say that when selected you want your row to change the color of the text and the color of the background. Your XML layout can be written like :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/menu_item_background_selector"
    android:orientation="horizontal" >

<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:textColor="@drawable/menu_item_text_selector" />

Now, in the drawable folder you create menu_item_background_selector.xml and menu_item_text_selector.xml.

menu_item_text_selector.xml :

 <?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_activated="true"
     android:color="#FFF">
</item>

<item android:state_pressed="true"
     android:color="#FFF">
</item>

<item android:state_pressed="false"
     android:color="#000">
</item>

</selector>

The text will be white when selected.

Then do something similar for your background: (remember that you're not forced to use color but you can also use drawables)

menu_item_background_selector.xml :

<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">


        <item android:state_activated="true"
        android:color="#0094CE">
        </item>

        <item android:state_pressed="true"
        android:color="#0094CE">
        </item>

        <item android:state_pressed="false"
        android:color="#ACD52B">
        </item>


      </selector>

Here the background is blue when selected and green when it is not selected.

The main element I was missing was android:state_activated. There's indeed (too) many states : activated,pressed,focused,checked,selected...

I'm not sure if the exemple I gave with android:state_activated and android:state_pressed is the best and cleanest one but it seems to work for me.

But I didn't need to make my own class in order to get a Custom CheckableRelativeLayout (which was dirty and scary) nor I used CheckableTextViews. I don't know whyothers used such methods, it maybe depends on the Api level.

aga
  • 27,954
  • 13
  • 86
  • 121
Jecimi
  • 4,113
  • 7
  • 31
  • 40
  • 4
    Great answer! However, I can confirm this doesn't work in Gingerbread and earlier. (state_activated was added in Honeycomb, API level 11.) – benkc Feb 13 '13 at 21:17
  • 2
    You forgot to mention that you should use the `Mylistview.getCheckedItemPosition();` method to retrieve the position of your selected item. – Alex Semeniuk Jul 01 '13 at 06:33
  • @AlexSemeniuk and you just saved me so much time. THANK YOU. – Constantin Jul 29 '13 at 22:19
  • 6
    Just to be safe you shouldn't be setting Mylistview.setChoiceMode to 1. You should set it to AbsListView.CHOICE_MODE_SINGLE. This is currently equal to 1 but they could change it in future api versions. – Jason Teplitz Aug 21 '13 at 14:39
  • 8
    I do not know for others, but for my part, I was having a RelativeLayout for the background selector and the app was crashing (`XML Inflate exception`). I managed to get it work by changing `android:color` with `android:drawable` in the background drawable (you can use a color anyway). Anyway thanks for the solution it worked great! – Quentin Klein May 26 '14 at 19:37
  • Thank You! You've helped me immensely with the nightmare that is Android ListView selectors. – Francis McGrew Nov 24 '14 at 08:24
  • Thanks for the answer. Still I would like to point out that the `menu_item_background_selector.xml` is combining two states (activated and pressed) and should fully be expanded. **The example above would not work if the order of items is changed.** – Draško Kokić Feb 03 '15 at 12:33
  • 3
    Thanks. and thanks @Quentin for the tip, otherwise It could have cost me few hours! When using android:drawable had to use @color/ that specified in the colors.xml. example: android:drawable="@color/pressed_color" where "pressed_color" is defined in colors.xml as #CACFD2 – madu Oct 26 '16 at 19:17
  • Thanks. It works, but it's still confusing: Although conceptually there is a "selected" state, we have to call setItemChecked (and not, for example, setSelected). And in the XML selector items it's different again - state_activated and state_pressed instead of state_selected and state_checked. Leaves me feeling I should be really doing it differently. – Dabbler Dec 30 '16 at 17:49
15

Try AbsListView.performItemClick(...)

See this post on how to use performItemClick.

Community
  • 1
  • 1
AlikElzin-kilaka
  • 34,335
  • 35
  • 194
  • 277
10

This is what worked for me:

1) Set the choice behavior for the List.

 mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

2) Sets the checked state of the specified position.

mListView.setItemChecked(1,true); //Don't make the same mistake I did by calling this function before setting the listview adapter.

3) Add a new style inside the style resource (res/values) like this:

<style name="activated" parent="android:Theme.Holo">
<item name="android:background">@android:color/holo_green_light</item>
</style>

Feel free to use whichever colours you like.

4) Use the previously defined style in your ListView:

<ListView
        android:id="@+id/listview"
        style="@style/activated"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"/>

Or in the layout you use as row.

<?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="wrap_content" 
  style="@style/activated"
>
  <!--widgets for your row here-->

</LinearLayout>

Hope that helps anyone!

Axel
  • 1,674
  • 4
  • 26
  • 38
4

Try mListView.setSelection(position);

J_D
  • 3,526
  • 20
  • 31
  • 5
    It work, for instance if I put `mListView.setSelection(20)` it sends the user to the 20th item of the list.But do you have any idea to make the item stay selected (or highlighted) ? – Jecimi May 28 '12 at 19:02
  • 3
    Well, in fact it is better in my case to go with `listview.setItemChecked(position, true);` (see my answer if you want more details). Thanks for your answer anyway :). – Jecimi May 28 '12 at 23:22
  • `setSelection()` will only work if not in touch mode (documentation clearly states this). – Alex Semeniuk Jul 01 '13 at 06:35
  • @AlexSemeniuk I think we have different perspectives of "clearly", where does documentation state this? Also, for the record, I agree `setSelection()` does not seem to work in touch mode. – Constantin Jul 29 '13 at 22:18
  • 1
    @Constantin Here you go: http://developer.android.com/reference/android/widget/ListView.html#setSelection(int). The phrase **"If in touch mode, the item will not be selected but it will still be positioned appropriately."** is nowhere more "clearly" than it currently is. – Alex Semeniuk Jul 30 '13 at 06:40
4

Jecimi's answer worked for me except for small part. I would like to share it for others. Calling list.setItemChecked( 0, true ); in onCreate() of FragmentActivity did not work. In getView() of adapter list.getCheckedItemPosition( ) returned -1.

I have to call this method from protected void onPostCreate( Bundle savedInstanceState ).

0

You can use ListView#setSelection(int)

asenovm
  • 6,397
  • 2
  • 41
  • 52
0
package com.example.samsung;

import com.example.samsung.*;
import com.example.samsung.R;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;

public class Firstscreen extends Activity implements OnItemSelectedListener {
    Button btn;
     Spinner sp;
     public String[] product = { "ML-1676P/XIP","SLM2021W/XIP","SL-M2826ND/XIP","SL-M2826ND/XIP","SL-M2826ND/XIP","SL-M3320ND/XIP","SL-M3820ND/XIP","SL-M4020ND/XIP"};  


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_firstscreen);
        btn = (Button) findViewById(R.id.bn);
        sp= (Spinner) findViewById(R.id.sp);
    }
        public void button (View v){
            {

        Intent i = new Intent(Firstscreen.this,ML1676P.class);
        startActivity(i);
        }

        Spinner s1 = (Spinner) findViewById(R.id.sp);
        ArrayAdapter<String> adapter 
        = new ArrayAdapter<String>(this, 
                android.R.layout.simple_spinner_item, product); // find other layout parameters
        s1.setAdapter(adapter);
        s1.setOnItemSelectedListener(new OnItemSelectedListener()
        {

            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1,
                    int arg2, long arg3) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub

            }

    });
    }

    private Object product() {
            // TODO Auto-generated method stub
            return null;
        }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.firstscreen, menu);
        return true;
    }

    @Override
    public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
            long arg3) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0) {
        // TODO Auto-generated method stub


    }



}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".Firstscreen"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#FF35B5E5"
        android:layout_centerInParent="true"
        android:text="CHOOSE THE PRODUCT FROM THE LIST" />

    <Spinner
        android:id="@+id/sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:drawSelectorOnTop="true" />

    <Button
        android:id="@+id/bn"
        android:layout_width="285dp"
        android:layout_height="wrap_content"
        android:text="       GO             " 
        android:onClick="button"/>


</LinearLayout>

select an item in a listview it should go to the specific selected item page when button is clicked how to do it.The code is snippet above

Gopal Singh Sirvi
  • 4,539
  • 5
  • 33
  • 55
0

I do like this:

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            try {
                int pos = 0;
                listview.performItemClick(null, pos, listview.getItemIdAtPosition(pos) );
            } catch (Exception e) {
                e.printStackTrace();
            }
        } 
    }
Faisal Shaikh
  • 3,900
  • 5
  • 40
  • 77
-1

Just add the following line to the layout of your custom listview:

android:background="?android:attr/activatedBackgroundIndicator"

For a full working example see:

https://elimelec@bitbucket.org/elimelec/custombaseadapter.git

Undo
  • 25,519
  • 37
  • 106
  • 129
zibetto
  • 21
  • 2