在 Android 的自定义适配器中设置 Textview 的文本的问题
Posted
技术标签:
【中文标题】在 Android 的自定义适配器中设置 Textview 的文本的问题【英文标题】:Issue in setting Textview's text in Custom Adapter for Android 【发布时间】:2015-01-04 05:11:34 【问题描述】:我无法在自定义适配器的getView()
方法中设置 textview 的 setText 属性。
我已经尝试了以下解决方案,但它对我不起作用:
Solution One Solution Two Solution ThreeListview.xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/imgLayout"
android:layout_
android:layout_>
<ListView
android:id="@+id/list"
android:layout_
android:layout_
android:layout_marginTop="40dp"
android:divider="@null"
android:dividerHeight="5dp"
android:scrollbars="none" />
</RelativeLayout>
以下是我的 keep_resing xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/customRowLayout"
android:layout_
android:layout_
android:layout_marginTop="20dp"
android:orientation="horizontal" >
<RelativeLayout
android:layout_
android:layout_ >
<LinearLayout
android:layout_
android:layout_
android:layout_alignParentLeft="true"
android:orientation="vertical" >
<ImageButton
android:id="@+id/Btn"
android:layout_
android:layout_
android:layout_marginLeft="10dp"
android:background="@drawable/thumb_down_disabled" />
<TextView
android:layout_
android:layout_
android:gravity="center_horizontal"
android:text="@string/resing"
android:textColor="#357EC7"
android:textSize="10sp" />
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:layout_centerHorizontal="true"
android:orientation="vertical" >
<TextView
android:id="@+id/lyricsTxt"
android:layout_
android:layout_
android:layout_gravity="center_horizontal" />
<RelativeLayout
android:id="@+id/parentLayout"
android:layout_
android:layout_
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:background="@drawable/playing_view"
android:orientation="horizontal" >
<TextView
android:id="@+id/helloTxt"
android:layout_
android:layout_
android:layout_centerInParent="true"
android:layout_marginLeft="5dp"
android:singleLine="true"
android:text="Hello"
android:textColor="#357EC7"
android:textSize="14sp" />
<ImageView
android:layout_
android:layout_
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:background="@drawable/volume" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:layout_alignParentRight="true"
android:orientation="vertical" >
<ImageButton
android:id="@+id/keepBtn"
android:layout_
android:layout_
android:layout_marginRight="10dp"
android:background="@drawable/thumb_up_disabled" />
<TextView
android:layout_
android:layout_
android:gravity="center_horizontal"
android:text="@string/keep"
android:textColor="#357EC7"
android:textSize="10sp" />
</LinearLayout>
</RelativeLayout>
下面是我的适配器代码:
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.simpleframework.xml.stream.Position;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Handler;
import android.os.PowerManager;
import android.sax.StartElementListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class KeepReSingAdapter extends BaseAdapter implements OnClickListener
/*********** Declare Used Variables *********/
private Activity activity;
private ArrayList data;
private static LayoutInflater inflater = null;
public Resources res;
SongCue tempValues = null;
int i = 0;
private ArrayList<SongCue> songCue;
private int cueIndex = 0;
private String selectedSongId;
private MediaPlayer mMediaPlayer;
ViewHolder holder;
View vi;
boolean right_button_flag, left_button_flag;
SessionManager session;
// int left_button_flag;
/************* CustomAdapter Constructor *****************/
public KeepReSingAdapter(Activity a, ArrayList d, Resources resLocal)
/********** Take passed values **********/
activity = a;
data = d;
res = resLocal;
/*********** Layout inflator to call external xml layout () ***********/
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
selectedSongId = SessionManager.getInstance(
activity.getApplicationContext()).getString(
AppConstants.SONG_ID);
right_button_flag = false;
left_button_flag = false;
// Session class instance
session = new SessionManager(activity.getApplicationContext());
/******** What is the size of Passed Arraylist Size ************/
public int getCount()
if (data.size() <= 0)
return 1;
return data.size();
public Object getItem(int position)
return position;
public long getItemId(int position)
return position;
/********* Create a holder Class to contain inflated xml file elements *********/
public static class ViewHolder
public TextView lyricsTxt, helloTxt;
// public TextView text1;
public ImageButton leftBtn, rightBtn;
public RelativeLayout parentLayout;
public LinearLayout rowLayout;
// public TextView textWide;
// ImageView image;
/****** Depends upon data size called for each row , Create each ListView row *****/
public View getView(final int position, View convertView, ViewGroup parent)
vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.keep_resing, null);
holder = new ViewHolder();
holder.lyricsTxt = (TextView) vi.findViewById(R.id.lyricsTxt);
holder.helloTxt = (TextView) vi.findViewById(R.id.helloTxt);
holder.leftBtn = (ImageButton) vi.findViewById(R.id.reSingBtn);
holder.rightBtn = (ImageButton) vi.findViewById(R.id.keepBtn);
holder.parentLayout = (RelativeLayout) vi
.findViewById(R.id.parentLayout);
holder.rowLayout = (LinearLayout) vi
.findViewById(R.id.customRowLayout);
vi.setTag(holder);
else
holder = (ViewHolder) vi.getTag();
if (data.size() <= 0)
else
/***** Get each Model object from Arraylist ********/
tempValues = null;
tempValues = (SongCue) data.get(position);
holder.lyricsTxt.setText(tempValues.getLyric());
List<Song> AllSong = SplashScreen_Activity.songs;
if (selectedSongId != null)
for (Song tempsong : AllSong)
if (tempsong.songId.equals(selectedSongId))
songCue = (ArrayList<SongCue>) tempsong.songCues.songCue;
else
holder.parentLayout.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Toast.makeText(activity.getApplicationContext(),
" " + position, Toast.LENGTH_SHORT).show();
holder.helloTxt.setText("Test");
Toast.makeText(activity.getApplicationContext(),
holder.helloTxt.getText().toString(),
Toast.LENGTH_LONG).show();
);
vi.setOnClickListener(new OnItemClickListener(position));
return vi;
@Override
public void onClick(View v)
Log.v("CustomAdapter", "=====Row button clicked=====");
/********* Called when Item click in ListView ************/
private class OnItemClickListener implements OnClickListener
private int mPosition;
OnItemClickListener(int position)
mPosition = position;
@Override
public void onClick(View arg0)
问题是,我无法将文本视图文本更改为“测试”。
注意:如果我通过执行“holder.helloTxt.getText().toString()
”看到 Toast 中的值,它会显示“Test”。
我不知道为什么会出现这个问题。任何帮助将不胜感激。
谢谢
【问题讨论】:
你不需要把你的 setOnClickListener 放在外面 if (convertView == null) 吗? 请添加您的列表布局 @LucianoRodríguez :最初只是这样,但那也没有用。 @ChiragJain:列表的布局只是相对布局中的一个简单的ListView。 xml 文件,其中包含 listview 和另一个这是你好可见的? 【参考方案1】:我终于找到了我的问题的解决方案,并猜猜这是代码中的一个小更新。
我将代码更新为:
final ViewHolder holder;
在CustomAdapter
的getView()
内,而不是全局声明。
再次感谢大家的回答。
它帮助我详细研究了我的代码。
【讨论】:
我刚刚接受了 ypur 的回答,但你能解释一下为什么在创建类 final 后,代码可以正常工作。 @SalmanKhan 我遇到了同样的问题,所以我到达了这篇文章。添加“final”解决了我的问题,我知道为什么会这样。 “getView”方法在第一次加载列表视图时调用,或者当您滚动列表视图以使一些新项目出现(消失)在列表视图中时。因此,当您单击它时,不会调用 getView 方法,而是调用 onClick 方法。由于您在getView方法中只设置了持有者对象包含各种项目,所以当您单击它时,持有者对象不包含任何内容。 @SalmanKhan (...没有足够的字符,所以在这里继续) 如果您将持有者声明为最终,当首先调用 getView 时,将创建持有者对象并将其设置为包含 TextView,并且成为最终的。因此,当您稍后单击它时,该持有人仍然包含该 TextView。【参考方案2】:试试这个希望对你有帮助
vi = convertView;
if (vi == null)
vi = inflater.inflate(R.layout.xmlfile, null);
holder = new ViewHolder();
holder.helloTxt= (TextView) vi.findViewById(R.id.hearTxt);
holder.parentLayout= (RelativeLayout) vi
.findViewById(R.id.parentLayout);
vi.setTag(holder);
else
holder=(ViewHolder)vi.getTag();
holder.parentLayout.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Toast.makeText(activity.getApplicationContext(),
" " + position, Toast.LENGTH_SHORT).show();
holder.helloTxt.setText("Test");// not required
// just change the value of text in your list(which you are passing to the adapter) at corresponding position and then notify the list
notifyDataSetChanged();
Toast.makeText(activity.getApplicationContext(),
holder.helloTxt.getText().toString(),
Toast.LENGTH_LONG).show();
);
return vi;
它将显示文本“test”,但当您滚动时,它会再次更改为其原始值,因此您还必须更改列表中的值,并将其发送给适配器
在您的情况下,问题还在于,当您更新 TextView 的文本时,它会暂时更新,这就是您在 Toast 中获取 TextView 文本的原因。但是为了在 ListView 中显示更新的文本,您必须通知 List。但是当你这样做时,你的 TextView 会重置为原始值。因此,您所要做的就是获取一个全局 String 变量并将其初始化为您想要的任何初始值
private String yourText="initial text"
并在 getView() 中将 TextView 文本设置为此变量,如下所示
holder.helloTxt.setText(yourText);
当你点击你的 parentLayout 时,只需为这个字符串分配你想要的值并通知列表
yourText="test";
notifyDataSetChanged();
这样就可以了。但是请记住,这仅在您有单行时才有效,如果您有多行,则必须采用 String 数组。
【讨论】:
您是否更改了要传递给适配器的列表中的值? 实际上,我的问题是我有列表项,在里面我有一个包含文本视图的相对布局。现在点击相对布局,我想更改文本视图文本。所以,我的文本将是静态的。 你的意思是说你有单行??如果没有,你是如何膨胀你的行的?将您的整个适配器代码放在清晰的位置以及如何在 Activity 中设置列表视图 是的,我有单行。 我在你的 ViewHolder 类中没有找到这个 TextView holder.helloTxt 你也没有在任何地方初始化它??【参考方案3】:如果convertView
not 为空,您是否执行holder = vi.getTag();
?
当已经创建视图以将其重新初始化为原来的状态时,这是必要的。
【讨论】:
【参考方案4】:问题是,我无法将文本视图文本更改为“测试”。
你做错了。假设您的适配器由String
组成。我所期望的是,
if (convertView == null)
// inflate stuff
// create older
// set the older in the converView's tag
else
// retriewholder
// here you set the String in the holder at position:
String tmpString = getItem(position);
holder.helloTxt.setText(tmpString);
holder.parentLayout.setTag(position);
在onClick内部,可以通过标签对象检索位置,更新数据集中的String并调用notifyDataSetChanged
【讨论】:
【参考方案5】:您的问题是您没有触摸父布局。确保您的手指可以触摸到 parentLayout,您可以为其添加填充。或者你可以试试
holder.helloTxt.setOnClickListener(...)
而不是 parentLayout。
【讨论】:
【参考方案6】:我见过很多方法,但对我来说最简单的方法是将组件视图传递给适配器。然后,您可以根据需要进行更改。请参阅下面的示例:
Link
【讨论】:
以上是关于在 Android 的自定义适配器中设置 Textview 的文本的问题的主要内容,如果未能解决你的问题,请参考以下文章
Android - 如何使用适配器类中的代码在布局文件中设置图像?
BaseAdapter 类不会在 Asynctask 中设置适配器 - Android