【问题标题】:Android ImageButton in ListView row clicklistener not respondingListView行clicklistener中的Android ImageButton没有响应
【发布时间】:2014-09-30 12:00:40
【问题描述】:

我有一个 ListView,其中的行包含 ImageButtons(如下所示的“O”):

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

我发现第一行有间歇性行为。起初,点击监听器上的图像按钮似乎并没有被调用只是顶行。我发现按钮 do 的 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 );     
}   

【问题讨论】:

  • ListView 拦截事件(例如滚动)。面对同样的问题,我被建议改用LinearLayout
  • @AntoineMarques:如果我摆脱 ListView,我将如何实现滚动?这听起来像是一个相当大的变化。
  • @SparkyNZ 请给我看你的getView和列表项布局的代码
  • 只需将LinearLayout 放入ScrollView。确实很烦人,因为除此之外不能直接使用ListView 的适配器机制。也许有更好的解决方案,使用ListView 并指定您的项目是可点击的。
  • @mmlooloo:我已经添加了请求的位。我的列表视图是分组/分段列表视图。如果它是节中的第一行,我会增加行标题视图的大小。

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


【解决方案1】:

我认为你的 getView 有一些问题,首先你没有膨胀任何布局,你使用的是 getView 的构造函数,这是个坏主意,你必须膨胀 convertView 或使用传递给你的那个,但在你想要的情况下要为不同的位置使用不同的视图,我认为您应该始终为 convertView 充气。我建议您查看此问题和答案以及我的答案下面的 cmets,以更好地了解 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;

【讨论】:

  • 我明天试试。仅 XML 中的可聚焦行没有帮助,因此我将尝试将单击侦听器分配移动到您建议的位置。我担心似乎有多个任务正在发生。
  • 它没有区别:(即使点击监听器被分配了多次,这也不应该是一个问题——它只分配相同的引用。我不会每次都创建图像视图- 我只是在做一个 findById() 所以它不像我在实例化多个 ImageViews。点击被“缓冲”的事实表明 onclicklisteners 正在被调用..只是没有立即 - 我不明白。几乎看起来好像他们在错误的线程上???
  • 我想使用 TraceView 或调试器来了解实际发生的情况,但我现在觉得我的深度不够。
  • 看看这个:stackoverflow.com/questions/25091281/… 这是你的问题,不是吗?我认为您想要的功能在您的项目中是相同的,并且通过可点击的小部件连续响应式点击
  • 还有一件事:你调用 if( mSectioned == false ) return super.getView( position, convertView, parent );在超级构造函数中,您是否为您的图像按钮分配了点击侦听器?
猜你喜欢
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 2011-01-23
  • 1970-01-01
相关资源
最近更新 更多