当我在写一个android应用的时候遇到了这样一个需求:
有个ListView,里面的item都有图片和文字,当一个item被点击的时候显示在此item上显示图片和一个进度条,当另一个item被点击的时候隐藏上一次被电击item的图片和进度条,显示当前被点击item的图片和进度条
我的有关代码是这样的,用的是simpleAdapter
我的思路是就这样的,先把ListView的所有item遍历,隐藏我该隐藏的控件,然后显示当前被点击item的要显示的控件(progressbar和playing_effect)
不过问题出现了,点击之后的效果特别卡,不知道怎么回事点击40-50次之后就出现手机内存不足的情况,难道我的思路一开始是错误的吗?还是需要优化?耗内存是怎么回事啊
谢谢
public class MainActivity extends AppCompatActivity {
ArrayList<Boolean> itemState = new ArrayList<>();
int checkedItemIndex = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int s=0;s<20;s++){
itemState.add(false);
}
class AudioListAdapter extends SimpleAdapter{
public AudioListAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
//
if (itemState.get(position)){
// 设置点击状态
v.findViewById(R.id.progressBar).setVisibility(View.VISIBLE);
v.findViewById(R.id.playing_effect).setVisibility(View.VISIBLE);
}else {
// 设置未点击状态
v.findViewById(R.id.progressBar).setVisibility(View.GONE);
v.findViewById(R.id.playing_effect).setVisibility(View.GONE);
}
//
return v;
}
}
final ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();
for (int i = 0; i < 10; i++){
HashMap<String,Object> map = new HashMap<String, Object>();
map.put("song","song name "+i);
map.put("singer","singer "+i);
map.put("currentTime","01:3"+i);
map.put("allTime","04:5"+i);
listItem.add(map);
}
final ListView listView = (ListView)findViewById(R.id.listView);
final AudioListAdapter audioListAdapter = new AudioListAdapter(
this,
listItem,
R.layout.item,
new String[]{"song","singer","currentTime","allTime"},
new int[]{R.id.song,R.id.singer,R.id.currentTime,R.id.allTime}
);
listView.setAdapter(audioListAdapter);
// onclick
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//
if (checkedItemIndex>=0){
itemState.set(checkedItemIndex,false);
}
checkedItemIndex = position;
itemState.set(position,true);
audioListAdapter.notifyDataSetChanged();
//
}
});
}
@Override
public void onStart(){
super.onStart();
}
}
上面我把所有代码给贴出来的,我按楼下回复里的想法去做的,我发现结果同样很卡,内存耗得更快,大神们看一下吧
谢谢
上記の 2 人は、リストを自分で管理し、getView のリストのステータスに応じて異なるビューを描画することを明確にしました。
リーリー以前のメソッドでは、すべての itemView のインスタンスを走査して作成する必要があり、CPU とメモリに大きな負荷がかかるため、アイテムの数が不明な場合は走査せずに保存することをお勧めします。最後のクリックだけで十分です。
このような疑似コードを書きました
----------------------------------区切り線----------- ------ ----
を作成/再利用する必要があります。getView 部分のコードに問題があります。ここでは、convertView
私のアイデアをお話しします。
アイテムのクリック ステータスをアダプターに保存します。クリックするたびに、アダプター内の特定のアイテムの特定の属性を更新するだけで済みます。そして、getView では、この属性に基づいてさまざまな処理が実行されます。
listViewのアダプターのgetViewメソッドに表示/非表示のロジックを記述し、クリックされたときにnotifyDataSetChangedを呼び出すだけです
3 階の正解は、クリックするたびに新しいブール値リストを作成し、まず添え字 currentitemindex の item 属性を false に変更し、添え字の item 属性を設定します。位置を true にします。次に、currentitemindex を更新します。最後にアダプター
を更新します。