当我点击列表行中的按钮时,我基本上尝试隐藏并在列表行中显示文本。我在getView()方法中为按钮添加了onClick(),然后调用了notifyDataSetChanged()。但它没有用。文本可见性没有变化。这是我的自定义适配器代码:
public class ListAdapter extends BaseAdapter {
private Context context;
private List<String> mListQuestion = null;
private List<String> mListAnswer = null;
ViewHolder holder = null;
boolean flag = false;
public ListAdapter(Context context, List<String> question, List<String> answer ) {
this.mListQuestion = question;
this.mListAnswer = answer;
this.context = context;
}
@Override
public Object getItem(int position)
{
return mListQuestion.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getCount() {
return mListQuestion.size();
}
@Override
@SuppressWarnings("deprecation")
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
{
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.list_faq_item, null);
holder = new ViewHolder();
holder.tvQuestion = (TextView) convertView.findViewById(R.id.text);
holder.tvAns = (TextView) convertView.findViewById(R.id.anstext);
holder.ivArrow = (Button)convertView.findViewById(R.id.arrow_expand);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.tvQuestion.setText(mListQuestion.get(position));
holder.tvAns.setText(mListAnswer.get(position));
holder.ivArrow.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if (flag == false)
{
Logger.d("arrow clicked when flag is false");
holder.tvAns.setVisibility(View.VISIBLE);
holder.ivArrow.setBackgroundResource(R.drawable.up_arrow);
flag = true;
}
else if (flag == true)
{
Logger.d("arrow clicked when flag is true");
holder.tvAns.setVisibility(View.GONE);
holder.ivArrow.setBackgroundResource(R.drawable.down_arrow);
flag = false;
}
notifyDataSetChanged();
}
});
return convertView;
}
static class ViewHolder {
TextView tvQuestion;
TextView tvAns;
Button ivArrow;
}
}
有人可以告诉我这里做错了什么。 在此先感谢。
-Arindam。
答案 0 :(得分:3)
public class ListAdapter extends BaseAdapter {
private Context context;
private List<String> mListQuestion = null;
private List<String> mListAnswer = null;
ViewHolder holder = null;
private List<Boolean> textViewVisibileState;
public ListAdapter(Context context, List<String> question, List<String> answer ) {
this.mListQuestion = question;
this.mListAnswer = answer;
this.context = context;
this.textViewVisibileState=new ArrayList<>(Arrays.asList(new Boolean[getCount()]));
Collections.fill(this.textViewVisibileState,false);
}
@Override
public Object getItem(int position)
{
return mListQuestion.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getCount() {
return mListQuestion.size();
}
@Override
@SuppressWarnings("deprecation")
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
{
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.list_faq_item, null);
holder = new ViewHolder();
holder.tvQuestion = (TextView) convertView.findViewById(R.id.text);
holder.tvAns = (TextView) convertView.findViewById(R.id.anstext);
holder.ivArrow = (Button)convertView.findViewById(R.id.arrow_expand);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.tvQuestion.setText(mListQuestion.get(position));
holder.tvAns.setText(mListAnswer.get(position));
if(textViewVisibileState.get(position))
{
holder.tvAns.setVisibility(View.GONE);
holder.ivArrow.setBackgroundResource(R.drawable.down_arrow);
}
else
{
Logger.d("arrow clicked when flag is false");
holder.tvAns.setVisibility(View.VISIBLE);
holder.ivArrow.setBackgroundResource(R.drawable.up_arrow);
}
holder.ivArrow.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if (textViewVisibileState.get(position))
{
textViewVisibileState.set(position,false);
}
else
{
textViewVisibileState.set(position,true);
}
notifyDataSetChanged();
}
});
return convertView;
}
static class ViewHolder {
TextView tvQuestion;
TextView tvAns;
Button ivArrow;
}
}
这会奏效。
答案 1 :(得分:1)
调用notifyDataSetChanged()
会导致ListView
重建所有内容。它将删除其子视图,为所有可见的项目调用getView()
,因此您将重新绑定这些项目的所有数据。
但您的数据实际上并没有改变。您还没有修改问题列表中的任何内容,因此再次绑定数据毫无意义。相反,您尝试更改ViewHolder
对象中的某些内容,但无法保证convertView
后notifyDataSetChanged()
与{C}}之前的位置相同,因此它与#39;某些其他项目可能受到影响(或者根本没有?)。
尝试从notifyDataSetChanged()
删除对OnClickListener
的通话。可见性更改应该会导致视图层次结构的重新布局,但只要您没有告诉ListView
数据已更改,它就应该保留所有当前的子级。
答案 2 :(得分:0)
创建适配器的实例,例如C/A
,将其设置为Adapter myAdapter = new Adapter
或listview
,例如recyclerview
,并且每次向其添加新数据时调用{{1 }}
答案 3 :(得分:0)
变量flag
对对象holder
不具有上下文敏感性。所以flag
在你的情况下总是=假。最初setVisibility(View.GONE)
怎么样?然后setVisibility(View.VISIBLE)
仅在点击ivArrow时。