Android ImageButton in ListView row clicklistener not responding

ε祈祈猫儿з 提交于 2019-12-13 05:19:23

问题


I have a ListView with rows that contain ImageButtons (shown as 'O' below):

[<-------TextView-------> O O O]
[<-------TextView-------> O O O]

I am finding that the first row has intermittent behaviour. At first it appeared that the image button onclicklisteners were not being called for just the top row. What I have found is that the onclicklisteners for the buttons do get called, but the clicks seem to be queued/buffered until I click on the row itself.

I will happily post some code if nobody knows the reason for this but my code is quite large and would need pruning before posting here. I am using a cursor adapter and custom viewbinder but the click listeners are assigned within the onCreate() of my activity.

The click listeners themselves I assign to the image button objects within the setViewValue() method of my CustomViewBinder class.

I haven't used a ViewHolder (ConvertView etc) - is this my problem? It does look as though the click listeners are being assigned 3 times for every row even though I only do so if the columnIndex is equal to 1.

Here is the row item XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_header"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:background="@drawable/row_selector"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_header"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0"
        android:layout_gravity="center_vertical"
        android:paddingLeft="4dp"
        android:background="@color/listSection"
        android:text=""
        android:textColor="@android:color/white"
        android:textStyle="bold"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal" >

    <!--
      ~ Use android:layout_weight so that this view will take up all the space
      ~ remaining when no other view has specifed its weight.
     -->
    <TextView
        android:id="@+id/lv_tune"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1"
        android:layout_marginLeft="10dp"
        android:text="Tune"
        android:textSize="20sp"
        android:textColor="@color/lvForeground"/>

    <!-- 
      ~ android:gravity is for the gravity in the View itself, while
      ~ android:layout_gravity is for the gravity of the View in it's
      ~ ViewGroup(container), in this case it may not be what you intended to
      ~ do, so I removed it for you.
     -->

    <ImageView
        android:id="@+id/ibAddPlaylist"
        android:layout_width="40dp"
        android:layout_height="34dp"
        android:layout_gravity="center"
        android:visibility="visible"
        android:src="@drawable/clipboard30x30grey" />

    <ImageView
        android:id="@+id/ibLikeHate"
        android:layout_width="40dp"
        android:layout_height="34dp"
        android:layout_gravity="center"
        android:visibility="visible"
        android:src="@drawable/heart1_30x30grey" />

    <ImageView
        android:id="@+id/ivPlay"
        android:layout_width="40dp"
        android:layout_height="34dp"
        android:layout_gravity="center"
        android:visibility="invisible"
        android:src="@drawable/play_30x30" />

  </LinearLayout>
</LinearLayout>

And here is the getView() method:

       @Override
       public View getView( int position, View convertView, ViewGroup parent )
       {
         final View view = super.getView( position, convertView, parent );
         final TextView text = (TextView) view.findViewById( R.id.lv_tune );
         final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) text.getLayoutParams();

         if( params != null )
         {
           int hei = params.height;

           if( IsStartOfAlphaSection( position ) )
           {
             // PDS: Looking at the layout for the TextView here..
             if( hei == LayoutParams.WRAP_CONTENT )
             {
               // PDS: But modifying the layout of the parent view..
               // view.setBackgroundColor( 0xFFDDDDDD );

               // PDS: Parent does not have LinearLayout - uses
               // AbsListView.LayoutParams
//*** BELOW LINE IS THE PROBLEM ..
               view.setLayoutParams( new AbsListView.LayoutParams( AbsListView.LayoutParams.MATCH_PARENT, g_NormalRowHeight + g_SectionHeaderHeight ) );
               view.requestLayout();
//***
             }
           }
           else
           {
             // PDS: Normal line

             // PDS: Looking at the layout for the TextView here..
             if( hei == LinearLayout.LayoutParams.WRAP_CONTENT )
             {
               // PDS: But modifying the layout of the parent view..
               // view.setBackgroundColor( Color.WHITE );
               view.setLayoutParams( new AbsListView.LayoutParams( AbsListView.LayoutParams.MATCH_PARENT, g_NormalRowHeight ) );
               view.requestLayout();
             }
           }
         }

         return view;
       }

I have highlighted the line(s) that are causing my problem. What I do is make the row height bigger for items that are group/section headers. This changes the layout that is used and also seems to mess up the click handlers for the imageviews on the first row. It also causes touching of the first row to continuously highlight the first row. Click on any other row and the higlight disappears.

UPDATE: Taking mmlooloo's suggestions into account, the below code seems to be working for me. Looks pretty ugly though (so did the original code that I posted too! ;-) )

public View getView( int position, View convertView, ViewGroup parent )
{
     final View view;

     LayoutInflater li = (LayoutInflater) mContext.getSystemService( Activity.LAYOUT_INFLATER_SERVICE );

     if( IsStartOfAlphaSection( position ) )
     {
       view = li.inflate( R.layout.like_hate_row_header,  parent, false );
     }
     else
     {
       view = li.inflate( R.layout.like_hate_row,  parent, false );
     }

     // NOT calling super.getView() stops ViewBinder::setViewValue() from being called
     super.getView( position, view, parent );     
}   

回答1:


I think your getView has some issues, first you do not inflate any layout and you are using the constructor of the getView thats bad idea, you must inflate convertView or using the one passes to you, But in your case that you want to use different view for different position i think you should always inflate convertView. and I recommend you to see this question and answer and the comments of below of my answer to get better sense about convertView.

android list array adapter.notifydatasetchanged not updating view correctly

So if i want to solve your problem i do it in this way: first create two XML files, one represents my none header item and another represents my header items. in the getView i check the position and if it must be header i inflate it by header xml else i inflate it by none header xml, so it will become something like this:

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

        LayoutInflater inflater = 
                (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        View view;
        if(position == header){
              view = inflater.inflate(R.layout.header, parent, false);
              // here you must call finViewById of specific objects or imageButtons 
              //which appear in the header and assign them click listeners  
        }else{
             view = inflater.inflate(R.layout.none_header, parent, false);
              // here you must call finViewById of specific objects or imageButtons 
              //which appear in the NONE header and assign them click listeners 
        }

        return view;

}

and also setting focusable to false for each imageButton;



来源:https://stackoverflow.com/questions/25179222/android-imagebutton-in-listview-row-clicklistener-not-responding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!