带有 CursorAdapter 的 Android ListView 项目 onClick 仅在一些点击后工作

Posted

技术标签:

【中文标题】带有 CursorAdapter 的 Android ListView 项目 onClick 仅在一些点击后工作【英文标题】:Android ListView items onClick with CursorAdapter only working after some clicks 【发布时间】:2018-03-23 00:07:05 【问题描述】:

这是ListFragment

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        View root = inflater.inflate(R.layout.fragment_list, container, false);

        listList = (ListView) root.findViewById(R.id.list_list);
        mListAdapter = new ListCursorAdapter(getActivity(),null);
        FloatingActionButton addFab = (FloatingActionButton) root.findViewById(R.id.fabAdd);
        addFab.setFocusable(false);
        addFab.setFocusableInTouchMode(false);

        mDBAdapter = new DBAdapter(getContext());
        mDBAdapter.open();

        id = new ArrayList<Integer>();
        nombres = new ArrayList<String>();
        latitudes = new ArrayList<Double>();
        longitudes = new ArrayList<Double>();
        descripciones = new ArrayList<String>();
        categorias = new ArrayList<Integer>();


        listList.setAdapter(mListAdapter);

        empty = (TextView) root.findViewById(R.id.tvEmpty);
        Cursor listas = mDBAdapter.getListaListas();
        if(listas==null || listas.getCount()<=0) empty.setVisibility(View.VISIBLE);

        listList.setClickable(true);
        AdapterView.OnItemClickListener myListViewClicked = new AdapterView.OnItemClickListener() 
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) 
                cur = mDBAdapter.getListaListas();
                int id_lis;
                String name_lis;
                if (cur.moveToFirst()) 
                    for (int k=0;k<i;k++)
                        cur.moveToNext();
                    
                
                id_lis = cur.getInt(0);
                name_lis = cur.getString(1);
                Intent intent = new Intent(getContext(), MarkerListActivity.class);
                intent.putExtra("numLista", id_lis);
                Log.i("id_lista", ""+ id_lis);
                intent.putExtra("nameLista", name_lis);
                startActivity(intent);
            
        ;

        listList.setOnItemClickListener( myListViewClicked );
        listList.setLongClickable(true);

它还有一个显示一些选项的长点击事件。起初,我将 Intent 放在那里,但这是常见的做法。

适配器是一个普通的 CursorAdapter,里面只有一个文本视图。 这些是 XML 文件:

list_item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_
    android:layout_
    android:descendantFocusability="blocksDescendants"
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/click"
        android:orientation="vertical"
        android:layout_
        android:layout_
        android:descendantFocusability="blocksDescendants"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false">

        <TextView
            android:id="@+id/list_name"
            android:layout_
            android:layout_
            android:paddingBottom="2dip"
            android:paddingTop="6dip"
            android:textColor="@color/colorPrimaryDark"
            android:textSize="20sp"
            android:textStyle="bold"
            android:layout_marginLeft="@dimen/activity_horizontal_margin"
            android:longClickable="true"
            android:clickable="false"
            android:focusableInTouchMode="false"
            android:focusable="false"/>


        <View xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_
            android:layout_
            android:layout_marginTop="8dp"
            android:background="#B6B6B6"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:clickable="false"
            />
    </LinearLayout>

</LinearLayout>

这是 fragment_list 布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".ListFragment"
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:descendantFocusability="blocksDescendants">

    <ListView
        android:id="@+id/list_list"
        android:layout_
        android:layout_
        android:divider="@null"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false" />

    <TextView
        android:id="@+id/tvEmpty"
        android:layout_
        android:layout_
        android:layout_gravity="center"
        android:layout_marginTop="5dp"
        android:hint="Ninguna lista para mostrar"
        android:textSize="25sp"
        android:textStyle="bold"
        android:visibility="invisible"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fabAdd"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:layout_
        android:layout_
        android:layout_gravity="bottom|end"
        android:layout_margin="12dp"
        android:tint="@android:color/white"
        app:fabSize="normal"
        app:srcCompat="@drawable/ic_action_add" />
</FrameLayout>

那么,我怎样才能让 onItemClick 通过简单的点击工作?打开新 Activity 总是需要点击四次或更多。

非常感谢。

【问题讨论】:

可能只需单击一下即可工作,但需要一些时间才能显示其他活动,因为您正在 UI 线程中执行数据库操作!同时,您认为它不起作用并再次单击,这给您的印象是它需要多次单击。为什么不将OnItemClickListeneronItemClick 方法放入ToastLog.d 消息中,看看是否只需单击即可打印 我也试过了,吐司有时只出现,多次点击后:( Toast 应该在cur = mDBAdapter.getListaListas(); 上面的第一行你正在做数据库操作,最好使用AsyncTask。我会尽快准备一个答案。 cur = mDBAdapter.getListaListas();...cursor iteration to position... 为什么?相反,您应该以正常方式为AdapterView 使用CursorAdapter 调用AdapterView.getItemAtPosition(position) 并将其转换为Cursor ... 我尝试了好几天,如果我在 OnLongClick 方法中使用该代码,它就可以工作。那里没有问题,但谢谢@Selvin 【参考方案1】:

您的 onItemClicked 方法在 UI 线程上执行数据库操作。这是您应该避免的事情,它会导致糟糕的用户体验。将您的代码包装在 AsyncTaskexecute 中,如下所示:

@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) 
    Log.d("onItemClick", "clicked Item")
    AsyncTask task = new AsyncTask<Void, Void, Void>() 
    private int id_lis;
    private String name_lis;

     protected Long doInBackground(Void... voids) 
        cur = mDBAdapter.getListaListas();
        if (cur.moveToFirst()) 
            for (int k=0;k<i;k++)
                cur.moveToNext();
            
        
        id_lis = cur.getInt(0);
        name_lis = cur.getString(1);
    

     protected void onPostExecute(Long result) 
         Intent intent = new Intent(getContext(), MarkerListActivity.class);
        intent.putExtra("numLista", id_lis);
        Log.i("id_lista", ""+ id_lis);
        intent.putExtra("nameLista", name_lis);
        startActivity(intent);
     
 .execute();

【讨论】:

我这样做了,但发生的情况是一样的:点击有时有效,并且该代码无法打开任何内容,抱歉:/ 在另一个线程上进行迭代不会减少它的时间(因为创建线程的成本很高,所以它会花费更多时间)——它只会不会阻塞 UI 线程 是的,我尝试等待但没有任何反应,只有当我多次点击该项目@Selvin 第一次点击时连Log.d("onItemClick", "clicked Item") 消息都没有出现? 不,只有在多次点击后(有时是第一次,有时在 5 次点击后)@pleft

以上是关于带有 CursorAdapter 的 Android ListView 项目 onClick 仅在一些点击后工作的主要内容,如果未能解决你的问题,请参考以下文章

带有 CursorAdapter 的 Android ListView 项目 onClick 仅在一些点击后工作

在 cursoradapter 中从 ListView 中删除项目

使用自定义 CursorAdapter 时 ListView 未显示在活动中

Android CursorAdapter的使用

VFP CursorAdapter 起步二(作者:Dung Hennig 译者:fbilo)

如何使用 CursorAdapter 将 Filter 设置为 ListView?