完全无响应的 Android 自定义适配器
Posted
技术标签:
【中文标题】完全无响应的 Android 自定义适配器【英文标题】:Completely Unresponsive Android Custom Adapter 【发布时间】:2015-06-25 00:04:06 【问题描述】:似乎无法确定我的适配器的问题。我试图在checkedTextView
下方放置一个进度条,以尽量减少元素数量和相对布局的麻烦(将加载栏放在下方,将单选按钮放在textView
的右侧)。
protected void onCreate(Bundle savedInstanceState)
...
connections = new ArrayList<WifiP2pClient>();//make an arraylist for the connections
listView = (ListView)findViewById(R.id.connectionsListView);//initialize the list view
adapter = new P2PClientArrayAdapter(this, android.R.layout.simple_List_item_single_choice, connections);//create an array adapter
listView.setAdapter(adapter);//attach the adapter to the listView
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
...
public class P2PClientArrayAdapter extends ArrayAdapter<WifiP2pClient>
private CheckedTextView checkedTextView;
private ProgressBar progressBar;
int lastRadioButtonPressed;
CheckedTextView lastPressedTextView;
public P2PClientArrayAdapter(Context context, int resource, List<WifiP2pClient> clients)
super(context, resource, clients);
lastRadioButtonPressed = -1;
lastPressedTextView = null;
@Override
public View getView(final int position, View convertView, ViewGroup parent)
View row = convertView;
WifiP2pClient client = getItem(position);
if(row == null)
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.row_layout, parent, false);
checkedTextView = (CheckedTextView)row.findViewById(R.id.clientToString);
progressBar = (ProgressBar)row.findViewById(R.id.clientProgressBar);
row.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if(position != lastRadioButtonPressed)
if(lastPressedTextView != null)
lastPressedTextView.setChecked(false);
lastRadioButtonPressed = position;
lastPressedTextView = checkedTextView;
checkedTextView.setChecked(true);
P2PClientArrayAdapter.this.notifyDataSetChanged();
);
checkedTextView.setText(client.toString());
progressBar.setProgress(client.getProgress());
return row;
目前,问题是适配器无响应。我使用异步任务更新WifiP2pClient
并经常调用notifyDataSetChanged()
,但UI 中显示的数据永远不会更新。此外,当我按下listView
时,什么也没有发生(甚至没有正常的黑色压下动画)。
如果我改用常规的ArrayListAdapter<String>
对象,arrayList
会正确更新,所以我知道其余代码可以正常工作,这 arrayAdapter
有问题。
编辑:我根据这篇文章将onClickListener()
放入getView()
:
How to use RadioGroup in ListView custom adapter?
EDIT2:通过使用@987654336 确保在视图不为空时正确更新checkedViewText
和progressBar
对象,我让适配器正确响应对其所做的更改和用户的按下@object 和视图的 setTag()
和 getTag()
功能。我将很快粘贴此代码。但是,我仍然没有让适配器为 getCheckedItemPosition()
返回正确的值。
【问题讨论】:
为什么要将 onclicklistener 放在适配器的 getView() 中?它应该在适配器本身上。 也许您可以将代码发布到您使用新数据更新适配器的位置? 【参考方案1】:在做了足够多的实验并幸运地休息之后,这是我完成的代码(为了将来的谷歌用户和比较起见)。
public class P2PClientArrayAdapter extends ArrayAdapter<WifiP2pClient>
//The viewholder object isn't neccessary but it allows us to Tag.set()
//with no indicies because we have it wrapped in one big object
private class ViewHolder
CheckedTextView checkedTextView;
ProgressBar progressBar;
int lastRadioButtonPressed;
CheckedTextView lastPressedTextView;
public P2PClientArrayAdapter(Context context, int resource, List<WifiP2pClient> clients)
super(context, resource, clients);
lastRadioButtonPressed = -1;
lastPressedTextView = null;
//I wasn't sure how to override ListView's getCheckedItemPosition()
//So I made my own and then changed the calling code.
public int getCheckedItemPosition()
return lastRadioButtonPressed;
//If you delete an element in your list, you have
//to reset the pointer or you'll have logic errors.
public void resetCheckedItemPosition()
lastRadioButtonPressed = -1;
lastPressedTextView = null;
@Override
public View getView(final int position, View convertView, ViewGroup parent)
View row = convertView;
WifiP2pClient client = getItem(position);
final ViewHolder viewHolder;
if(row == null)
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.row_layout, parent, false);
viewHolder = new ViewHolder();
viewHolder.checkedTextView = (CheckedTextView)row.findViewById(R.id.clientToString);
viewHolder.progressBar = (ProgressBar)row.findViewById(R.id.clientProgressBar);
row.setTag(viewHolder);
else
viewHolder = (ViewHolder)row.getTag();
row.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if(position != lastRadioButtonPressed)
if(lastPressedTextView != null)
lastPressedTextView.setChecked(false);
lastRadioButtonPressed = position;
lastPressedTextView = viewHolder.checkedTextView;
viewHolder.checkedTextView.setChecked(true);
);
viewHolder.checkedTextView.setText(client.toString());
viewHolder.progressBar.setProgress(client.getProgress());
return row;
【讨论】:
以上是关于完全无响应的 Android 自定义适配器的主要内容,如果未能解决你的问题,请参考以下文章