ListView onItemClickListener仅适用于自定义行的一部分

时间:2015-05-06 06:44:57

标签: android android-listview onitemlongclicklistener

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

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

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

android:descendantFocusability="blocksDescendants"已添加到我的ListView LinearLayout

android:clickable="false"ImageView

android:focusable="false"android:focusableInTouchMode="false"同时TextView s。

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

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>

5 个答案:

答案 0 :(得分:1)

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

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

如果还不够,请尝试设置

android:descendantFocusability="blocksDescendants

到text_listview_row.xml linearlayout&amp;

android:textIsSelectable="false"

到textview的text_listview_row.xml里面

<强>更新

实际上,我需要的只是一行android:descendantFocusability="blocksDescendants",而是在 text_listiew_row.xml LinearLayout父级内部( text_tab.xml <中不需要/强>)。谢谢!

答案 1 :(得分:0)

尝试在列表项视图xml( text_listview_row.xml )中为您的视图设置以下标记

android:focusable="false"

以便列表项单击将始终完美地工作

答案 2 :(得分:0)

我认为问题出在这一行:

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

之前添加日志以验证是否已成功调用该方法。

Log.d("TextTab", "onItemLongClick");
if (adapter.getItem(pos) != sampleItem) {
    ...

答案 3 :(得分:0)

这不是您的情况,但单击自定义布局项时遇到类似的问题。在寻找解决方案一个小时后,发现我在布局文件中将android:inputType设置为TextView,这阻止了onClick()侦听器 (不知道为什么)

请勿将android:inputType与TextView一起使用。

对我来说效果很好

答案 4 :(得分:0)

许多人问,列表中的TextViews的宽度不应与父级匹配。

即使将“ Focusable”设置为false,也不会起作用。 将TextView Width设置为wrap_content

<TextView
    android:id="@+id/itemchild"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    ...