Java 如何在Android中从ListView和Adapter中获取所选文本?
我花了几个小时试图解决这个问题,虽然我已经接近,但我没有得到我需要的结果。我有一个消息传递应用程序,它有一个自定义适配器和一个包含大约5个文本视图的listview。我的问题是当用户长按消息时检索文本。在尝试了各种方法之后,我最接近的方法是:Java 如何在Android中从ListView和Adapter中获取所选文本?,java,android,eclipse,listview,android-adapter,Java,Android,Eclipse,Listview,Android Adapter,我花了几个小时试图解决这个问题,虽然我已经接近,但我没有得到我需要的结果。我有一个消息传递应用程序,它有一个自定义适配器和一个包含大约5个文本视图的listview。我的问题是当用户长按消息时检索文本。在尝试了各种方法之后,我最接近的方法是: mListView.setOnItemLongClickListener( new AdapterView.OnItemLongClickListener (){ public boolean onIte
mListView.setOnItemLongClickListener( new AdapterView.OnItemLongClickListener
(){
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
final String test = ((TextView)v).getText().toString();
Log.i(TAG, "Received: " + test);
return true;
}
});
奇怪的是,我在最初几次成功地获得了正确的消息字符串,然后它就不想工作了。在查找错误之后,我尝试了多次清理项目,删除R.java文件,关闭Eclipse,但是没有任何效果
我也尝试过使用消息的位置号。当获取消息的位置号时,应用程序从未强制关闭,但是我无法获取附加到该位置消息的字符串。错误与尝试从整数转换为字符串有关:
String test = ((EditText)av.getItemAtPosition(pos)).getText().toString();
我的xml文件包括:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_margin="20dip"
android:background="@drawable/bubble_yellow"
android:gravity="left"
android:orientation="vertical"
android:visibility="invisible" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:paddingBottom="1dip"
android:paddingLeft="15dip"
android:paddingRight="20dip"
android:paddingTop="1dip"
android:singleLine="false"
android:text="Large Text"
android:longClickable="true"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:gravity="right"
android:paddingRight="20dip"
android:longClickable="true"
android:text="TextView" />
</LinearLayout>
<LinearLayout
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_margin="20dip"
android:background="@drawable/bubble_green"
android:orientation="vertical"
android:visibility="invisible" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="1dip"
android:paddingLeft="15dip"
android:paddingRight="20dip"
android:paddingTop="1dip"
android:singleLine="false"
android:longClickable="true"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:gravity="right"
android:longClickable="true"
android:paddingRight="20dip"
android:text="TextView" />
</LinearLayout>
</RelativeLayout>
更新3:我尽了最大努力遵循@MDragon00的建议,不幸的是,我的应用程序在长时间按下时仍然崩溃。我现在有:
mListView.setOnItemLongClickListener( new AdapterView.OnItemLongClickListener
(){
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
TextView textView1 = (TextView) v.findViewById(R.id.textView1);
TextView textView2 = (TextView) v.findViewById(R.id.textView2);
TextView textView3 = (TextView) v.findViewById(R.id.textView3);
TextView textView4 = (TextView) v.findViewById(R.id.textView4);
View.OnLongClickListener listener = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
TextView textView = (TextView) v;
String text = textView.getText().toString();
Log.i(TAG, "Text Selected = " + text);
return false;
}
};
textView1.setOnLongClickListener(listener);
textView2.setOnLongClickListener(listener);
textView3.setOnLongClickListener(listener);
textView4.setOnLongClickListener(listener);
return true;
}
});
}
mListView.setOnItemLongClickListener(新的AdapterView.OnItemLongClickListener
(){
长点击(AdapterView av、View v、int pos、long id){
TextView textView1=(TextView)v.findViewById(R.id.textView1);
TextView textView2=(TextView)v.findViewById(R.id.textView2);
TextView textView3=(TextView)v.findViewById(R.id.textView3);
TextView textView4=(TextView)v.findViewById(R.id.textView4);
View.OnLongClickListener=新建视图。OnLongClickListener(){
@凌驾
仅长按公共布尔值(视图v){
TextView TextView=(TextView)v;
String text=textView.getText().toString();
Log.i(标记,“选择的文本=”+文本);
返回false;
}
};
textView1.setOnLongClickListener(listener);
textView2.setOnLongClickListener(listener);
textView3.setOnLongClickListener(listener);
textView4.setOnLongClickListener(listener);
返回true;
}
});
}
每个参数在单击时的作用说明:
这里的问题是,av
是整个列表视图,而v
是整个行。您的行不只是由TextView组成,因此无法将其强制转换为TextView。换句话说,
final String test = ((TextView)v).getText().toString();
这不是一个好主意,因为父视图是相对的。更好的解决方案是执行以下操作:
ViewHolder viewHolder;
MessageModel array = data.get(position);
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = inflater.inflate(R.layout.message_item, null);
viewHolder.left =(LinearLayout)convertView.findViewById(R.id.left);
viewHolder.right =(LinearLayout)convertView.findViewById(R.id.right);
viewHolder.txt1 = (TextView) convertView
.findViewById(R.id.textView1);
viewHolder.txt3 = (TextView) convertView
.findViewById(R.id.textView3);
viewHolder.txt2 = (TextView) convertView
.findViewById(R.id.textView2);
viewHolder.txt4 = (TextView) convertView
.findViewById(R.id.textView4);
convertView.setTag(viewHolder);
TextView textView = (TextView) v.findViewById(R.id.idOfTextView);
String text = textView.getText().toString();
作为一个小建议,听起来您只需单击该项目,而不是长时间单击它。如果适合您的需要,请使用OnItemClickListener而不是OnItemLongClickListener
编辑:
根据您的评论,用户将单击/点击某个抽象行中多个文本视图中的某个文本视图,您希望获得这四个文本视图中的一个
为此,您需要在每个TextView上安装一个新的侦听器。如果没有看到适配器,我无法给出准确的答案,但是当您在适配器中膨胀/获取要提供给ListView的行视图时,请将OnClickListener设置为TextView。例如,使用一些伪代码:
// Get the textViews, to assign a listener to them
TextView textView1 = (TextView) v.findViewById(R.id.textView1);
TextView textView2 = (Textview) v.findViewById(R.id.textView2);
..... // Etc and so on
// Create this listener anywhere, including via making the adapter/class
// implement the listener and passing it in instead
View.OnClickListener listener = new View.OnClickListener(
@Override
public void onClick(View v) {
// Get the view as a TextView, as this will only be used
// with TextViews, so the only view to be passed
// will be Textviews
TextView textView = (TextView) v;
// Do whatever with that text, or however you want to use the view
String text = textView.getText().toString();
someFunction(text);
}
);
textView1.setOnClickListener(listener);
textView2.setOnClickListener(listener);
..... // Etc and so on
现在,如果您需要单击的精确行和精确文本视图中的文本,那么您需要使用两个侦听器(即,ListView上的一个和TextView上的一个)来获取适当的数据
编辑最终版本:
public class TestAdapter extends BaseAdapter {
Context mContext;
public TestAdapter (Context context, Data someData) {
this.mContext = context;
// Set up the data for your listView however
}
@Override
public int getCount() {
return howManyRows;
}
@Override
public Object getItem(int position) {
return objectAtPosition;
}
@Override
public long getItemId(int position) {
return 0;
} // Unnecessary, unless using databases
// The listener for the textViews, feel free to use different listeners
View.OnClickListener TextViewListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// Get the view as a TextView, as this will only be used
// with TextViews, so the only view to be passed
// will be Textviews
TextView textView = (TextView) v;
// Do whatever with that text, or however you want to use the view
String text = textView.getText().toString();
someFunction(text);
}
};
// Using the efficient pattern for recycling the views rather than using
// findViewById repeatedly
public static class ViewHolder{
public TextView textView1;
public TextView textView2;
public TextView textView3;
public TextView textView4;
// And any other view that's part of the row view that you need
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = null;
ViewHolder holder;
if(convertView == null) {
// Then gotta set up this row for the first time
LayoutInflater inflater =
(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.row_layout.xml, parent, false);
// Create a ViewHolder to save all the different parts of the row
holder = new ViewHolder();
holder.textView1 = (TextView) row.findViewById(R.id.textView1);
holder.textView2 = (TextView) row.findViewById(R.id.textView2);
holder.textView3 = (TextView) row.findViewById(R.id.textView3);
holder.textView4 = (TextView) row.findViewById(R.id.textView4);
// Make the row reuse the ViewHolder
row.setTag(holder);
}
else { // Otherwise, use the recycled view
row = convertView;
holder = (ViewHolder) row.getTag();
}
// Set the current row's Textview onClickListeners
// Note: You MAY be able to only set these once- feel free to set that
holder.textView1.setOnClickListener(TextViewListener);
holder.textView2.setOnClickListener(TextViewListener);
holder.textView3.setOnClickListener(TextViewListener);
holder.textView4.setOnClickListener(TextViewListener);
// Set up the rest of the views however you need
/*.....
......
*/
return row;
}
}
每个参数在单击时的作用说明: 这里的问题是,
av
是整个列表视图,而v
是整个行。您的行不只是由TextView组成,因此无法将其强制转换为TextView。换句话说,
final String test = ((TextView)v).getText().toString();
这不是一个好主意,因为父视图是相对的。更好的解决方案是执行以下操作:
ViewHolder viewHolder;
MessageModel array = data.get(position);
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = inflater.inflate(R.layout.message_item, null);
viewHolder.left =(LinearLayout)convertView.findViewById(R.id.left);
viewHolder.right =(LinearLayout)convertView.findViewById(R.id.right);
viewHolder.txt1 = (TextView) convertView
.findViewById(R.id.textView1);
viewHolder.txt3 = (TextView) convertView
.findViewById(R.id.textView3);
viewHolder.txt2 = (TextView) convertView
.findViewById(R.id.textView2);
viewHolder.txt4 = (TextView) convertView
.findViewById(R.id.textView4);
convertView.setTag(viewHolder);
TextView textView = (TextView) v.findViewById(R.id.idOfTextView);
String text = textView.getText().toString();
作为一个小建议,听起来您只需单击该项目,而不是长时间单击它。如果适合您的需要,请使用OnItemClickListener而不是OnItemLongClickListener
编辑:
根据您的评论,用户将单击/点击某个抽象行中多个文本视图中的某个文本视图,您希望获得这四个文本视图中的一个
为此,您需要在每个TextView上安装一个新的侦听器。如果没有看到适配器,我无法给出准确的答案,但是当您在适配器中膨胀/获取要提供给ListView的行视图时,请将OnClickListener设置为TextView。例如,使用一些伪代码:
// Get the textViews, to assign a listener to them
TextView textView1 = (TextView) v.findViewById(R.id.textView1);
TextView textView2 = (Textview) v.findViewById(R.id.textView2);
..... // Etc and so on
// Create this listener anywhere, including via making the adapter/class
// implement the listener and passing it in instead
View.OnClickListener listener = new View.OnClickListener(
@Override
public void onClick(View v) {
// Get the view as a TextView, as this will only be used
// with TextViews, so the only view to be passed
// will be Textviews
TextView textView = (TextView) v;
// Do whatever with that text, or however you want to use the view
String text = textView.getText().toString();
someFunction(text);
}
);
textView1.setOnClickListener(listener);
textView2.setOnClickListener(listener);
..... // Etc and so on
现在,如果您需要单击的精确行和精确文本视图中的文本,那么您需要使用两个侦听器(即,ListView上的一个和TextView上的一个)来获取适当的数据
编辑最终版本:
public class TestAdapter extends BaseAdapter {
Context mContext;
public TestAdapter (Context context, Data someData) {
this.mContext = context;
// Set up the data for your listView however
}
@Override
public int getCount() {
return howManyRows;
}
@Override
public Object getItem(int position) {
return objectAtPosition;
}
@Override
public long getItemId(int position) {
return 0;
} // Unnecessary, unless using databases
// The listener for the textViews, feel free to use different listeners
View.OnClickListener TextViewListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// Get the view as a TextView, as this will only be used
// with TextViews, so the only view to be passed
// will be Textviews
TextView textView = (TextView) v;
// Do whatever with that text, or however you want to use the view
String text = textView.getText().toString();
someFunction(text);
}
};
// Using the efficient pattern for recycling the views rather than using
// findViewById repeatedly
public static class ViewHolder{
public TextView textView1;
public TextView textView2;
public TextView textView3;
public TextView textView4;
// And any other view that's part of the row view that you need
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = null;
ViewHolder holder;
if(convertView == null) {
// Then gotta set up this row for the first time
LayoutInflater inflater =
(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.row_layout.xml, parent, false);
// Create a ViewHolder to save all the different parts of the row
holder = new ViewHolder();
holder.textView1 = (TextView) row.findViewById(R.id.textView1);
holder.textView2 = (TextView) row.findViewById(R.id.textView2);
holder.textView3 = (TextView) row.findViewById(R.id.textView3);
holder.textView4 = (TextView) row.findViewById(R.id.textView4);
// Make the row reuse the ViewHolder
row.setTag(holder);
}
else { // Otherwise, use the recycled view
row = convertView;
holder = (ViewHolder) row.getTag();
}
// Set the current row's Textview onClickListeners
// Note: You MAY be able to only set these once- feel free to set that
holder.textView1.setOnClickListener(TextViewListener);
holder.textView2.setOnClickListener(TextViewListener);
holder.textView3.setOnClickListener(TextViewListener);
holder.textView4.setOnClickListener(TextViewListener);
// Set up the rest of the views however you need
/*.....
......
*/
return row;
}
}
每个参数在单击时的作用说明: 这里的问题是,
av
是整个列表视图,而v
是整个行。您的行不只是由TextView组成,因此无法将其强制转换为TextView。换句话说,
final String test = ((TextView)v).getText().toString();
这不是一个好主意,因为父视图是相对的。更好的解决方案是执行以下操作:
ViewHolder viewHolder;
MessageModel array = data.get(position);
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = inflater.inflate(R.layout.message_item, null);
viewHolder.left =(LinearLayout)convertView.findViewById(R.id.left);
viewHolder.right =(LinearLayout)convertView.findViewById(R.id.right);
viewHolder.txt1 = (TextView) convertView
.findViewById(R.id.textView1);
viewHolder.txt3 = (TextView) convertView
.findViewById(R.id.textView3);
viewHolder.txt2 = (TextView) convertView
.findViewById(R.id.textView2);
viewHolder.txt4 = (TextView) convertView
.findViewById(R.id.textView4);
convertView.setTag(viewHolder);
TextView textView = (TextView) v.findViewById(R.id.idOfTextView);
String text = textView.getText().toString();
作为一个小建议,听起来您只需单击该项目,而不是长时间单击它。如果适合您的需要,请使用OnItemClickListener而不是OnItemLongClickListener
编辑:
根据您的评论,用户将单击/点击某个抽象行中多个文本视图中的某个文本视图,您希望获得这四个文本视图中的一个
为此,您需要在每个TextView上安装一个新的侦听器。如果没有看到您的适配器,我无法给出确切的答案,但是当您