android - ListView onItemClickListener 仅适用于部分自定义行

标签 android android-listview onitemlongclicklistener

我有一个自定义的 ListView,其中每行包含 3 个项目,一个 TextView(标题),一个 ImageView(占位符图标),和另一个 TextView(内容文本)。我在 ListView 上设置了一个 OnItemLongClickListener,它应该是当用户点击 ListView 中的项目时(应该是整行 3 个项目一起作为一个),然后会出现一个对话框,让他们可以选择删除整个项目,然后删除该单个列表项目的所有 3 个部分。

但长按标题 View 和图像不会触发监听器。只有当内容 TextView 被长按时,对话框才会出现,然后删除所有 3 个,但是单击行中的任意位置应该 这样做。然而事实并非如此。我需要找到一个解决方案,因为用户不知道只能点击内容 TextView,他们应该可以点击任何地方。

我在这里寻找解决方案,并尝试添加这些行,但没有任何效果:

android:descendantFocusability="blocksDescendants" 添加到我的 ListViewLinearLayout

android:clickable="false" 到我的 ImageView

android:focusable="false"android:focusableInTouchMode="false" 到两个 TextView

我没有其他可以尝试的东西。有什么想法吗?

enter image description here

更新

当我添加额外的行时,就像@Amrit 建议的那样(他的回答中的代码),长按时整个区域现在会弹出对话框,但它会在我单击的区域创建这种奇怪的色调,但前提是我单击标题 TextViewImageView 区域。奇怪的是,第二个 TextView 看起来仍然不错,并且会按预期生成对话框。虽然不确定如何摆脱这种错位的色调:

enter image description here

TextTab.java

package org.azurespot.cutecollection.texttab;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

import org.azurespot.R;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;


/**
 * Created by mizu on 2/8/15.
 */
public class TextTab extends Fragment {

    private ArrayList<PoemListItem> poems = new ArrayList<>();
    private ListViewPoemAdapter adapter;
    private ListView listView;
    String[] allSDCardFiles = null;
    StringBuilder text;
    PoemListItem wordsFromFile;
    File[] files;
    PoemListItem sampleItem;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.text_tab, container, false);
        adapter = new ListViewPoemAdapter(getActivity(), poems);
        // Attach the adapter to a ListView
        listView = (ListView) v.findViewById(R.id.text_list_view);
        listView.setAdapter(adapter);

        if(adapter.getCount() == 0) {
            // load contents of SD card
            loadSDCard();
        }

        setupListViewListener();

        return v;

    }

    private void loadSDCard(){

        try {
            // gets directory CuteWords from sd card
            File cuteWordsDir = new File(Environment.getExternalStoragePublicDirectory
                    (Environment.DIRECTORY_DOCUMENTS), "/Cute Words");

            if (!cuteWordsDir.exists()){
                cuteWordsDir.mkdir();
            }

            if (cuteWordsDir.isDirectory()) {
                // lists all files in CuteWords, loads in Files[] array
                files = cuteWordsDir.listFiles();

                for (File singleFile : files) {
                    //Read text from file, put each line into StringBuilder
                    text = new StringBuilder();

                    BufferedReader br = new BufferedReader(new FileReader(singleFile));
                    String line;

                    while ((line = br.readLine()) != null) {
                        text.append(line);
                        text.append('\n');

                        // get full file name with ext. and text in file
                        wordsFromFile = new PoemListItem(singleFile.getName(), text.toString());

                        adapter.add(wordsFromFile);
                        adapter.notifyDataSetChanged();
                    }
                }
            }

            // get number of files in CuteWords directory
            allSDCardFiles =  new String[files.length];

            // create a blank String version of PoemListItem
            sampleItem = new PoemListItem(" ", " ");

            // add the default icon/lines remaining to ArrayList (through adapter),
            // if less than 9 files on SD card
            for (int i = 0; i < (9 - allSDCardFiles.length); i++) {
                adapter.add(sampleItem);
            }
            adapter.notifyDataSetChanged();

        } catch(IOException e){
                e.printStackTrace();
            }
    }

    // so you can edit any of the list items
    private void setupListViewListener() {

        // to delete a list item
        listView.setOnItemLongClickListener(new ListView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> aView, View item,
                                                        final int pos, long id) {


                if (adapter.getItem(pos) != sampleItem) {

                    new AlertDialog.Builder(getActivity())
                            .setTitle("Delete")
                            .setMessage("Delete these cute words?")
                            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {
                                    // delete from ArrayList first
                                    poems.remove(pos);
                                    adapter.notifyDataSetChanged();

                                    // get file name then delete it
                                    String name = files[pos].getName();
                                    File file = new File(Environment.getExternalStorageDirectory(),
                                            "/Documents/Cute Words/" + name);
                                    file.delete();

                                    // clear list and adapter
                                    poems.clear();
                                    adapter.clear();
                                    adapter.notifyDataSetChanged();

                                    // after each item delete, must refresh load with new arrangement
                                    loadSDCard();

                                }
                            })
                            .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {

                                    // do nothing
                                    dialog.cancel();

                                }
                            })
                            .setIcon(android.R.drawable.ic_dialog_alert)
                            .show();

                    }

                return true;
            }
        });

    }
}

ListViewPoemAdapter

package org.azurespot.cutecollection.texttab;

import android.content.Context;
import android.text.InputType;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import org.azurespot.R;

import java.util.ArrayList;

/**
 * Created by mizu on 2/8/15.
 */
public class ListViewPoemAdapter extends ArrayAdapter<PoemListItem> {

    private TextView poemText;
    private TextView poemTitle;
    private ImageView poemPlaceholder;


    public ListViewPoemAdapter(Context context, ArrayList<PoemListItem> poems) {
        super(context, 0, poems);

    }

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

        PoemListItem poemListItem = getItem(position);

        if (convertView == null) {
            convertView = LayoutInflater.from(getContext())
                    .inflate(R.layout.text_listview_row, parent, false);
        }

        poemTitle = (TextView) convertView.findViewById(R.id.text_title);
        poemText = (TextView) convertView.findViewById(R.id.text);
        poemPlaceholder = (ImageView)convertView.findViewById(R.id.icon_placeholder_poem);

        poemText.setInputType(InputType.TYPE_CLASS_TEXT |
                              InputType.TYPE_TEXT_FLAG_MULTI_LINE |
                              InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);

        poemText.setMovementMethod(new ScrollingMovementMethod());

        poemPlaceholder.setBackgroundResource(R.drawable.ic_poem_placeholder);
        poemPlaceholder.setScaleType(ImageView.ScaleType.CENTER_CROP);
        poemPlaceholder.setLayoutParams(new LinearLayout.LayoutParams(150, 150));

        poemTitle.setText(poemListItem.getTitle());
        poemText.setText(poemListItem.getPoem());

        return convertView;

    }


}

text_tab.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:descendantFocusability="blocksDescendants"
    android:background="#2198bb">

    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/text_list_view"
        android:layout_centerHorizontal="true"
        android:layout_margin="10dp"
        android:scrollbarStyle="outsideOverlay"
        android:verticalScrollbarPosition="right"
        android:divider="@null"/>

</LinearLayout>

text_listview_row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:paddingBottom="20dp">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="false"
            android:id="@+id/icon_placeholder_poem"
            android:layout_marginRight="15dp"
            android:layout_marginEnd="15dp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/text_title"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:textSize="25sp"
            android:textStyle="bold|italic"
            android:hint="Title"
            android:ellipsize="start"/>


    </LinearLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/text"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:gravity="top"
        android:maxLines="10"
        android:inputType="textMultiLine"
        android:scrollHorizontally="false"
        android:scrollbars="vertical"
        android:textSize="20sp"
        android:ems="10"
        android:textStyle="italic"
        android:hint="Quote or poem, here."
        android:ellipsize="start"/>

    <!--Line in-between the rows-->
    <View
        android:layout_width="fill_parent"
        android:layout_height="2dp"
        android:background="#7e8287"
        android:paddingTop="20dp" />


</LinearLayout>

最佳答案

将 listView 项目中的所有 subview 设置为不可聚焦或不可点击。

android:focusable="false"
android:clickable="false"

如果不够尝试设置

android:descendantFocusability="blocksDescendants

到 text_listview_row.xml 线性布局 &

android:textIsSelectable="false"

到textview里面的text_listview_row.xml

更新

实际上我所需要的只是一行 android:descendantFocusability="blocksDescendants" 但在 text_listiew_row.xmlLinearLayout 父级中>(在 text_tab.xml 中不需要)。谢谢!

关于android - ListView onItemClickListener 仅适用于部分自定义行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30069411/

相关文章:

java - 如何使用未知节点将 Firebase 数据库中的值显示到 Firebase 回收 View ?

android - 为 Android 应用程序重置 TextView 在 Listview 行中的位置

java - SearchView 在 LongClick 操作后停止过滤

android - 在 ListView 中单击项目时,如何获取 sqlite 数据库中表的行 ID

c# - 从 DataTable 填充 ListView

java - 长按阻止扩展可扩展 ListView

android - 如何访问存储在 kotlin block 中的变量中的值

java - 如何停止 RecyclerView 适配器内的快照监听器?

android - Android ListView OnItemClickListener中获取点击坐标