Android 带有 LinkedHashMap 的 ListView - 滚动时乱序列表
Android ListView with LinkedHashMap - scrambled list when scrolling
我很难找到很多关于将 LinkedHashMap 与 ListView 一起用于 Android 的文档,但我能够使用以下内容正确填充列表。
不幸的是,当我滚动时,列表被打乱,就像我使用常规 HashMap 时一样。我不确定我做错了什么。
MainActivity.java(只是一部分):
public class MainActivity extends ListActivity {
private ListView dataList;
ArrayList<String> listItems=new ArrayList<String>();
ListViewAdapter adapter;
private ArrayList<LinkedHashMap<String, String>> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dataList = (ListView)findViewById(android.R.id.list);
list=new ArrayList<LinkedHashMap<String,String>>();
adapter=new ListViewAdapter(this, list);
dataList.setAdapter(adapter);
addItems();
}
public void addItems() {
LinkedHashMap<String,String> row = new LinkedHashMap<String, String>();
row.put(KEY_COLUMN, key);
row.put(FIRST_COLUMN, dateTime);
row.put(SECOND_COLUMN, data1);
row.put(THIRD_COLUMN, data2);
row.put(FOURTH_COLUMN, data3);
list.add(row);
adapter.notifyDataSetChanged();
}
}
ListViewAdapter Class
public class ListViewAdapter extends BaseAdapter{
public ArrayList<LinkedHashMap<String, String>> list;
Activity activity;
TextView txtKey;
TextView txtFirst;
TextView txtSecond;
TextView txtThird;
TextView txtFourth;
public ListViewAdapter(Activity activity,ArrayList<LinkedHashMap<String, String>> list){
super();
this.activity = activity;
this.list = list;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView == null){
LayoutInflater inflater = activity.getLayoutInflater();
convertView = inflater.inflate(R.layout.list_row_columns, null);
txtKey = (TextView) convertView.findViewById(R.id.row_key);
txtFirst = (TextView) convertView.findViewById(R.id.date_time);
txtSecond = (TextView) convertView.findViewById(R.id.data1);
txtThird = (TextView) convertView.findViewById(R.id.data2);
txtFourth = (TextView) convertView.findViewById(R.id.data3);
}
LinkedHashMap<String, String> map = list.get(position);
txtKey.setText(map.get(KEY_COLUMN));
txtFirst.setText(map.get(FIRST_COLUMN));
txtSecond.setText(map.get(SECOND_COLUMN));
txtThird.setText(map.get(THIRD_COLUMN));
txtFourth.setText(map.get(FOURTH_COLUMN));
return convertView;
}
}
最简单的解决方案是使用 ArrayAdapter
而不是滚动您自己的 BaseAdapter
subclass。但是,假设您真的想扩展 BaseAdapter
...
首先,从 class 声明中删除所有小部件(例如 TextView txtKey
),将它们移动到 getView()
.[=25= 中的局部变量]
然后,无论您是否正在扩充新布局,都填充这些局部变量。
其他改进:
当你有 Activity
时,永远不要使用 LayoutInflater.from()
。在 Activity
上调用 getLayoutInflater()
,因此您会得到一个了解您的主题和风格的 LayoutInflater
。
在 getView()
中使用 getItem()
而不是 list.get(position)
,因此 getView()
和 getItem()
保持同步。
我很难找到很多关于将 LinkedHashMap 与 ListView 一起用于 Android 的文档,但我能够使用以下内容正确填充列表。
不幸的是,当我滚动时,列表被打乱,就像我使用常规 HashMap 时一样。我不确定我做错了什么。
MainActivity.java(只是一部分):
public class MainActivity extends ListActivity {
private ListView dataList;
ArrayList<String> listItems=new ArrayList<String>();
ListViewAdapter adapter;
private ArrayList<LinkedHashMap<String, String>> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dataList = (ListView)findViewById(android.R.id.list);
list=new ArrayList<LinkedHashMap<String,String>>();
adapter=new ListViewAdapter(this, list);
dataList.setAdapter(adapter);
addItems();
}
public void addItems() {
LinkedHashMap<String,String> row = new LinkedHashMap<String, String>();
row.put(KEY_COLUMN, key);
row.put(FIRST_COLUMN, dateTime);
row.put(SECOND_COLUMN, data1);
row.put(THIRD_COLUMN, data2);
row.put(FOURTH_COLUMN, data3);
list.add(row);
adapter.notifyDataSetChanged();
}
}
ListViewAdapter Class
public class ListViewAdapter extends BaseAdapter{
public ArrayList<LinkedHashMap<String, String>> list;
Activity activity;
TextView txtKey;
TextView txtFirst;
TextView txtSecond;
TextView txtThird;
TextView txtFourth;
public ListViewAdapter(Activity activity,ArrayList<LinkedHashMap<String, String>> list){
super();
this.activity = activity;
this.list = list;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView == null){
LayoutInflater inflater = activity.getLayoutInflater();
convertView = inflater.inflate(R.layout.list_row_columns, null);
txtKey = (TextView) convertView.findViewById(R.id.row_key);
txtFirst = (TextView) convertView.findViewById(R.id.date_time);
txtSecond = (TextView) convertView.findViewById(R.id.data1);
txtThird = (TextView) convertView.findViewById(R.id.data2);
txtFourth = (TextView) convertView.findViewById(R.id.data3);
}
LinkedHashMap<String, String> map = list.get(position);
txtKey.setText(map.get(KEY_COLUMN));
txtFirst.setText(map.get(FIRST_COLUMN));
txtSecond.setText(map.get(SECOND_COLUMN));
txtThird.setText(map.get(THIRD_COLUMN));
txtFourth.setText(map.get(FOURTH_COLUMN));
return convertView;
}
}
最简单的解决方案是使用 ArrayAdapter
而不是滚动您自己的 BaseAdapter
subclass。但是,假设您真的想扩展 BaseAdapter
...
首先,从 class 声明中删除所有小部件(例如 TextView txtKey
),将它们移动到 getView()
.[=25= 中的局部变量]
然后,无论您是否正在扩充新布局,都填充这些局部变量。
其他改进:
当你有
Activity
时,永远不要使用LayoutInflater.from()
。在Activity
上调用getLayoutInflater()
,因此您会得到一个了解您的主题和风格的LayoutInflater
。在
getView()
中使用getItem()
而不是list.get(position)
,因此getView()
和getItem()
保持同步。