我有一个自定义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。
我没有其他任何可以尝试的东西。有什么想法吗?
更新
当我添加额外的行,比如@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>
答案 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"
...