ListView行中的Android ImageButton clicklistener没有响应

时间:2014-08-07 09:44:20

标签: android android-listview simplecursoradapter android-viewbinder android-viewholder

我有一个包含ImageButtons的行的ListView(显示为' O'下面):

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

我发现第一行有间歇性行为。起初,似乎没有为顶行调用图像按钮onclicklisteners。我发现的是按钮的onclicklisteners被调用,但点击似乎排队/缓冲,直到我点击行本身。

如果没有人知道原因,我会很乐意发布一些代码,但我的代码非常大,需要在发布之前进行修剪。我正在使用游标适配器和自定义视图绑定器,但是在我的活动的onCreate()中分配了单击侦听器。

单击侦听器本身我分配给CustomViewBinder类的setViewValue()方法中的图像按钮对象。

我还没有使用ViewHolder(ConvertView等) - 这是我的问题吗?看起来好像每个行都为点击侦听器分配了3次,即使我只是在columnIndex等于1的情况下这样做。

这是行项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>

这是getView()方法:

       @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;
       }

我突出显示导致我问题的行。我所做的是使组/节标题项的行高更大。这会更改所使用的布局,并且似乎也会弄乱第一行上的图像视图的点击处理程序。它还会导致触摸第一行以连续突出显示第一行。点击任何其他行,高光消失。

更新:考虑到mmlooloo的建议,下面的代码似乎对我有用。看起来很丑陋(我发布的原始代码也是如此!;-))

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 个答案:

答案 0 :(得分:0)

我认为你的getView有一些问题,首先你没有膨胀任何布局,而你正在使用getView的构造函数那个坏主意,你必须给convertView充气或使用一个传递给你,但在你的情况下,你想要为不同的位置使用不同的视图我认为你应该总是膨胀convertView。我建议你看看这个问题和答案,以及我的答案下面的评论,以便更好地了解convertView。

android list array adapter.notifydatasetchanged not updating view correctly

因此,如果我想解决您的问题,我会这样做: 首先创建两个XML文件,一个代表我的无头项目,另一个代表我的标题项。 在getView中我检查位置,如果它必须是标题我用标题xml对它进行膨胀,否则我用无标题xml对它进行膨胀,所以它会变成这样:

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;

}

并将每个imageButton的焦点设置为false;