當(dāng)我在寫(xiě)一個(gè)android應(yīng)用的時(shí)候遇到了這樣一個(gè)需求:
有個(gè)ListView,里面的item都有圖片和文字,當(dāng)一個(gè)item被點(diǎn)擊的時(shí)候顯示在此item上顯示圖片和一個(gè)進(jìn)度條,當(dāng)另一個(gè)item被點(diǎn)擊的時(shí)候隱藏上一次被電擊item的圖片和進(jìn)度條,顯示當(dāng)前被點(diǎn)擊item的圖片和進(jìn)度條
我的有關(guān)代碼是這樣的,用的是simpleAdapter
我的思路是就這樣的,先把ListView的所有item遍歷,隱藏我該隱藏的控件,然后顯示當(dāng)前被點(diǎn)擊item的要顯示的控件(progressbar和playing_effect)
不過(guò)問(wèn)題出現(xiàn)了,點(diǎn)擊之后的效果特別卡,不知道怎么回事點(diǎn)擊40-50次之后就出現(xiàn)手機(jī)內(nèi)存不足的情況,難道我的思路一開(kāi)始是錯(cuò)誤的嗎?還是需要優(yōu)化?耗內(nèi)存是怎么回事啊
謝謝
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)){
// 設(shè)置點(diǎn)擊狀態(tài)
v.findViewById(R.id.progressBar).setVisibility(View.VISIBLE);
v.findViewById(R.id.playing_effect).setVisibility(View.VISIBLE);
}else {
// 設(shè)置未點(diǎn)擊狀態(tài)
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();
}
}
上面我把所有代碼給貼出來(lái)的,我按樓下回復(fù)里的想法去做的,我發(fā)現(xiàn)結(jié)果同樣很卡,內(nèi)存耗得更快,大神們看一下吧
謝謝
歡迎選擇我的課程,讓我們一起見(jiàn)證您的進(jìn)步~~
The two people above have already made it clear that you maintain a list yourself, and then draw different Views according to the status of the list in getView.
Previously, your method needed to traverse and create instances of all itemViews, which put a lot of pressure on the CPU and memory, so it would get stuck. It is best not to traverse when the number of items is unknown, and save the last one. Just click on the index.
I just wrote some pseudo code, something like this
ArrayList<Boolean> list = new ArrayList<>();
int listClickedItemIndex = -1;
public View getView(int position, View convertView, ViewGroup parent) {
if(list.get(position)){
//設(shè)為點(diǎn)擊狀態(tài)
}else{
//設(shè)為未點(diǎn)擊狀態(tài)
}
return convertView;
}
public void onItemClick(int position){
if(listClickedItemIndex >= 0){
list.set(listClickedItemIndex,false);
}
listClickedItemIndex = position;
list.set(position,true);
adapter.notifyDataSetChanged();
}
----------------------------------Dividing line---------------- -----
There is a problem with the code in your getView part. Here you should create/reuse convertView
Let me tell you my thoughts:
Store the click status of the item in the adapter. Each time you click, you only need to update a certain attribute of the specific item in the adapter. Then perform different processing in getView based on this attribute.
Write the display/hide logic in the getView method of the adapter of listView, and just call notifyDataSetChanged when clicked
Correct answer on Floor 3: Create a new boolean list to save the status of each item. Each time you click, first change the item attribute of the subscript currentitemindex to false, and set the item attribute of the subscript position to true. Then update the currentitemindex. Finally refresh the adapter