4

I am having an issue with the items in this list view. Normal behaviour is that when user taps in one item, the background color changes to orange. This is not happening to my app, and I can't figure out why.

The main.xml has just a:

<android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

The fragment's xml has only a:

<ListView
        android:id="@android:id/list"
        style="@style/MyListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

The view that I inflate inside the listView item is:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/textViewName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="5dp"
        android:layout_toRightOf="@+id/imageView1"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/imageView1"
        android:layout_alignLeft="@+id/textViewName"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginRight="10dp"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:src="@drawable/bottom_arrow" />

</RelativeLayout>

The style I defined for the ListView is:

<style name="MyListView" parent="@android:style/Widget.ListView.White">
        <item name="android:listSelector">@drawable/list_subject_selector</item>
        <item name="android:cacheColorHint">@android:color/transparent</item>
        <item name="android:background">@drawable/list_subject_selector</item>
    </style>

And the list_subject_selector drawable is:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- touch down -->
    <item android:drawable="@drawable/list_subject_focused" android:state_pressed="true"/>
    <!-- selected -->
    <item android:drawable="@drawable/list_subject_unfocused" android:state_focused="false" android:state_pressed="false" android:state_selected="true"/>
</selector>

I have no idea why this is happening... I am testing with Android ICS.

Any ideas?

Thanks everyone, Felipe

UPDATE 1 This is the ListFragment code:

public class MyFragment extends ListFragment {
    private ListAdaptor adapter;
    private InternalDB db;
    Context mContext;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mContext = getActivity();
        db = new InternalDB(getActivity());
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        ArrayList<EventVO> listVO = db.getSummaryEvents(true);
        adapter = new ListAdaptor(mContext, R.layout.event_inflate, listVO);
        setListAdapter(adapter);            
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        LinearLayout rl = (LinearLayout) inflater.inflate(R.layout.general_list, container, false);
        return rl;
    }

    private class ListAdaptor extends ArrayAdapter<EventVO> {
        private ArrayList<EventVO> listVO;

        public ListAdaptor(Context context, int textViewResourceId, ArrayList<EventVO> items) {
            super(context, textViewResourceId, items);
            this.listVO = items;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;
            if (v == null) {
                v = ViewGroup.inflate(getContext(), R.layout.event_inflate, null);
            }
            final EventVO o = listVO.get(position);
            TextView fullName = (TextView) v.findViewById(R.id.textViewName);
            fullName.setText(o.getUserName());

            //removed part of the code for brevity

            v.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    Intent i = new Intent(mContext, EventDetailsActivity.class);
                    i.putExtra("USER_ID", o.getUserId());                       
                    startActivity(i);
                }
            });
            return v;
        }
    }
}

UPDATE 2 It now works! That was very annoying. This I did to make it work:

The xml file that I was using to inflate had:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"
        android:focusable="true"
        android:focusableInTouchMode="true" >

I changed to:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

But, what I think that really made the change was this: Inside the onActivityCreated()

list = getListView();
        list.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                ListAdaptor la = (ListAdaptor)arg0.getAdapter();
                EventVO vo = la.getItem(arg2);
                Intent i = new Intent(mContext, EventDetailsActivity.class);
                i.putExtra("USER_ID", vo.getUserId());
                i.putExtra("IS_BORROWED", true);
                startActivity(i);
            }

The important is the line list = getListView(); I wasn't getting the ListView through this piece of code. I was getting the listView at the onCreateView() method, with a findViewById. I suppose that I was losing the link with the real ListView object.

Thanks to everyone who helped me! :)

Felipe });

Felipe Caldas
  • 2,492
  • 3
  • 36
  • 55

2 Answers2

2

Try changing your list selector. Currently the second drawable is only used when a item in your ListView is not focused or pressed and is selected. I don't really understand how you want your selector to look, but if "@drawable/list_selector_unfocused" is how you want the list selector to look normally, just remove all the other attributes, which means that "@drawable/list_selector_focused" would be used only when the item is pressed.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- touch down -->
<item android:drawable="@drawable/list_subject_focused" android:state_pressed="true"/>
<!-- selected -->
<item android:drawable="@drawable/list_subject_unfocused" />

Alex Curran
  • 8,818
  • 6
  • 49
  • 55
  • Do you mean changing the drawable selector to: That didnt work, unfortunately. Thanks – Felipe Caldas May 28 '12 at 17:07
  • No sorry, I wasn't very clear. I've edited my answer, that should be okay. If not, please explain when you are trying to show "@drawable/list_subject_focused" and when "@drawable/list_subject_unfocused" – Alex Curran May 28 '12 at 17:23
  • Hi. Thanks for the help the focused drawable should be when user taps on the ListView's item the unfocused should be when nothing is happening. I did try your suggestion but, unfortunately, it didnt work. Cheers! – Felipe Caldas May 28 '12 at 17:27
1

I found that when I was adding ListView layouts to pure Fragments you would loose a lot of the freebies the old ListActivity and such provided in the background. I would suggest that you change away from using a pure Fragment to using a ListFragment and you can watch all that awesomeness come back with no need to play about with selector drawables.

The 'Swell' and 'Tide' tabs in our application are both ListFragments within a ViewPager and look like this;

ListFragment within a pager with highlighting (original ICS is a bit darker than shown here)

BrantApps
  • 6,362
  • 2
  • 27
  • 60
  • Hi OcleanLife. First of all, what a beautiful designed screen you've got there :) I changed from Fragment to ListFragment and, unfortunately, did not work. I updated my post with the ListFragment code. Would you be able to review it and tell me if there's something I am missing? Many thanks – Felipe Caldas May 28 '12 at 15:51
  • Oh, by the way: just tried removing the setOnClickListener and adding the list.setOnItemClickListener in the onActivityCreated method and the listener is not being triggered at all :( – Felipe Caldas May 28 '12 at 16:00
  • Are you using the Android Support library to work with Fragments or your target application is for Android 3.0+ ? – Felipe Caldas May 28 '12 at 16:03
  • Hey Felipe, I am trailing a similar set-up myself. Will get back to you shortly. I am using ActionBarSherlock v4.0 which leverages the android-support-v4 jar. Highly recommended. That boy Jake is good. – BrantApps May 28 '12 at 16:14
  • Oh, I might not need to trial anything. With ````ListFragment```` and ````ListActivity````s you do not need to register a listener to the view in the manner described in your adapter class. Override ````onListItemClick```` at the ListFragment level and put your activity starting code there. Perhaps by virtue of the very fact you were registering this other listener over the in-built one it was shadowing the in-built functionality. – BrantApps May 28 '12 at 16:18
  • Hi OceanLife I added to my class declarion: implements OnItemClickListener, and a simple toast inside the onItemClick() method. Removed the setOnClickListener inside the adapter as well No luck... I guess I will try using the ActionBarSherlock hoping it can save the problem! – Felipe Caldas May 28 '12 at 16:49
  • Hey Felipe! No, no delete *all* of your special listeners, don't implement anything and override the ListFragment's [onListItemClick](http://developer.android.com/reference/android/app/ListFragment.html#onListItemClick(android.widget.ListView,%20android.view.View,%20int,%20long)). Put your activity starting code there. I am confident it will work- i just tried it on my app. – BrantApps May 28 '12 at 16:54
  • Hey again :) What is the activity starting code? Is it the code I have in the ListFragment's onActivityCreated() method? – Felipe Caldas May 28 '12 at 17:00
  • The 3 lines that start the ````EventDetailsActivity````, Line 1: your intent, Line 2: your bundle info & Line 3: startActivity. SO is asking we move this over to chat now. I'll be back online later. Just have a think and look at a few other ````ListFragment```` implementations. You are close. – BrantApps May 28 '12 at 17:05
  • So, here's what I have: public class MyFragment extends ListFragment And: @Override public void onListItemClick (ListView l, View v, int position, long id) { Toast.makeText(mContext, "Test", Toast.LENGTH_SHORT).show(); } – Felipe Caldas May 28 '12 at 17:05
  • That also didnt work... I am wondering if the implementation of com.viewpagerindicator.TitlePageIndicator by Jake Wharton is somehow conflicting with the listener – Felipe Caldas May 28 '12 at 17:08
  • Hi OceanLife. Thanks for your time I still didn't get this thing working, I will keep on looking what could be the root cause. And, of course, if you have some time to chat, I would very much appreciate it. – Felipe Caldas May 28 '12 at 17:29
  • Hey OceanLife, when you have some time, can we quickly have a chat? I have one small doubt regarding restarting the lifecycle of a Fragment and maybe you can help me :) – Felipe Caldas May 28 '12 at 18:41
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/11840/discussion-between-oceanlife-and-felipe-caldas) – BrantApps May 28 '12 at 21:31