我有一个自定义的 ListView
,其中每行包含 3 个项目,一个 TextView
(标题),一个 ImageView
(占位符图标),和另一个 TextView
(内容文本)。我在 ListView
上设置了一个 OnItemLongClickListener
,它应该是当用户点击 ListView
中的项目时(应该是整行 3 个项目一起作为一个),然后会出现一个对话框,让他们可以选择删除整个项目,然后删除该单个列表项目的所有 3 个部分。
但长按标题 View 和图像不会触发监听器。只有当内容 TextView
被长按时,对话框才会出现,然后删除所有 3 个,但是单击行中的任意位置应该 这样做。然而事实并非如此。我需要找到一个解决方案,因为用户不知道只能点击内容 TextView
,他们应该可以点击任何地方。
我在这里寻找解决方案,并尝试添加这些行,但没有任何效果:
android:descendantFocusability="blocksDescendants"
添加到我的 ListView
的 LinearLayout
。
android:clickable="false"
到我的 ImageView
。
android:focusable="false"
和 android:focusableInTouchMode="false"
到两个 TextView
。
我没有其他可以尝试的东西。有什么想法吗?
更新
当我添加额外的行时,就像@Amrit 建议的那样(他的回答中的代码),长按时整个区域现在会弹出对话框,但它会在我单击的区域创建这种奇怪的色调,但前提是我单击标题 TextView
或 ImageView
区域。奇怪的是,第二个 TextView
看起来仍然不错,并且会按预期生成对话框。虽然不确定如何摆脱这种错位的色调:
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/