Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android之ListView數據錯誤解決方法

Android之ListView數據錯誤解決方法

編輯:關於Android編程

ListView——“點贊”狀態屏幕滑動數據解決方法

我們在使用ListView時候,可能一行數據有名次、頭像、昵稱、補充文字/數據說明、“點贊”人數及圖標,如下圖“微信運動界面”所示。

\

而當我們有較多行數據,需要滑動屏幕時,這些“點贊”圖標的選擇狀態就會錯亂。還是以上圖為例,假如當前設備的屏幕可以顯示6行數據,總共需要顯示9行數據;我們點贊了第1個好友,但是沒有顯示出來的第7個好友的點贊圖標卻變“紅”了。這就是數據錯亂問題,那麼我們應該如何解決呢?

請看我下面的例子(在下面的Demo中,“點贊”圖標我換成了可以更換背景色的Button,紅色代表已經點贊了)。首先,我們先來看關鍵代碼:

 

private class PlatformWithStateChangeAdapter extends BaseAdapter{
        LayoutInflater mLayoutInflater = null;
        public PlatformWithStateChangeAdapter(Context context) {
            this.mLayoutInflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            return itemInfoList.size();
        }

        @Override
        public Object getItem(int position) {
            return null != itemInfoList ? itemInfoList.get(position) : null;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            final ItemInfo itemInfo = (ItemInfo) getItem(position);
            if (convertView == null){
                holder = new ViewHolder();
                convertView = mLayoutInflater.inflate(R.layout.activity_button_state_change_list,null);

                holder.img = (ImageView) convertView.findViewById(R.id.ivImg_btnstatechange);
                holder.title = (TextView) convertView.findViewById(R.id.tvTitle_btnstatechange);
                holder.info = (TextView) convertView.findViewById(R.id.tvInfo_btnstatechange);
                holder.btnIsSelected = (Button) convertView.findViewById(R.id.btnDetail_btnstatechange);

                final ViewHolder finalHolder = holder;
                holder.btnIsSelected.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        ItemInfo itemDetails = (ItemInfo) finalHolder.btnIsSelected.getTag();

                        if (itemDetails.isSelected()){
                            finalHolder.btnIsSelected.setBackgroundResource(R.color.green);
                            itemDetails.setSelected(false);
                        }
                        else {
                            finalHolder.btnIsSelected.setBackgroundResource(R.color.red);
                            itemDetails.setSelected(true);
                        }
                 
                    }
                });
                convertView.setTag(holder);
                holder.btnIsSelected.setTag(itemInfo);             
            }
            else {
                holder = (ViewHolder) convertView.getTag();
                holder.btnIsSelected.setTag(itemInfo);               
            }
            //避免滑屏時出現數據錯亂重復
            if (itemInfo.isSelected()){
                holder.btnIsSelected.setBackgroundResource(R.color.red);
            }
            else {
                holder.btnIsSelected.setBackgroundResource(R.color.green);
            }
            holder.img.setImageResource(itemInfo.getImg());
            holder.title.setText(itemInfo.getTitle());
            holder.info.setText(itemInfo.getInfo());
            return convertView;
        }
    }
我們來看一下運行效果:

 

\
 

全部代碼:

 

ButtonStateChangeActivity.java

 

 

package com.example.administrator.listviewdemo;

import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2016/9/4.
 */
public class ButtonStateChangeActivity extends AppCompatActivity{

    ListView lvPlatforms = null;
    List itemInfoList = null;
    PlatformWithStateChangeAdapter platformWithStateChangeAdapter = null;

    @Override
    protected void onCreate( Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_button);

        itemInfoList = getData();
        lvPlatforms = (ListView) findViewById(R.id.lvPlatforms);
        platformWithStateChangeAdapter = new PlatformWithStateChangeAdapter(this);
        lvPlatforms.setAdapter(platformWithStateChangeAdapter);

        ActionBar actionbar = getSupportActionBar();
        actionbar.setTitle(R.string.actionBarTitle_btnstatechange);
        actionbar.setDisplayHomeAsUpEnabled(true);
        actionbar.setDisplayShowHomeEnabled(true);

    }

    private List getData(){
        List itemInfos = new ArrayList<>();
        ItemInfo itemInfo = new ItemInfo("Android01","I am Android!",R.mipmap.ic_launcher,false);
        itemInfos.add(itemInfo);
        itemInfo = new ItemInfo("Apple01","I am Apple!",R.mipmap.apple02,false);
        itemInfos.add(itemInfo);
        return itemInfos;
    }

    private final class ViewHolder{
        private ImageView img;
        private TextView title;
        private TextView info;
        private Button btnIsSelected;
    }

    private class PlatformWithStateChangeAdapter extends BaseAdapter{
        LayoutInflater mLayoutInflater = null;
        public PlatformWithStateChangeAdapter(Context context) {
            this.mLayoutInflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            return itemInfoList.size();
        }

        @Override
        public Object getItem(int position) {
            return null != itemInfoList ? itemInfoList.get(position) : null;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            final ItemInfo itemInfo = (ItemInfo) getItem(position);
            if (convertView == null){
                holder = new ViewHolder();
                convertView = mLayoutInflater.inflate(R.layout.activity_button_state_change_list,null);

                holder.img = (ImageView) convertView.findViewById(R.id.ivImg_btnstatechange);
                holder.title = (TextView) convertView.findViewById(R.id.tvTitle_btnstatechange);
                holder.info = (TextView) convertView.findViewById(R.id.tvInfo_btnstatechange);
                holder.btnIsSelected = (Button) convertView.findViewById(R.id.btnDetail_btnstatechange);

                final ViewHolder finalHolder = holder;
                holder.btnIsSelected.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {                     
                        ItemInfo itemDetails = (ItemInfo) finalHolder.btnIsSelected.getTag();

                        if (itemDetails.isSelected()){
                            finalHolder.btnIsSelected.setBackgroundResource(R.color.green);
                            itemDetails.setSelected(false);
                        }
                        else {
                            finalHolder.btnIsSelected.setBackgroundResource(R.color.red);
                            itemDetails.setSelected(true);
                        }                      
                    }
                });
                convertView.setTag(holder);
                holder.btnIsSelected.setTag(itemInfo);            
            }
            else {
                holder = (ViewHolder) convertView.getTag();
                holder.btnIsSelected.setTag(itemInfo);             
            }

            //避免滑屏時出現數據錯亂重復
            if (itemInfo.isSelected()){
                holder.btnIsSelected.setBackgroundResource(R.color.red);
            }
            else {
                holder.btnIsSelected.setBackgroundResource(R.color.green);
            }
            holder.img.setImageResource(itemInfo.getImg());
            holder.title.setText(itemInfo.getTitle());
            holder.info.setText(itemInfo.getInfo());
            return convertView;
        }
    }

    final int updateMenuItemId = 100;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuItem updateMenuItem = menu.add(0,updateMenuItemId,0,"刷新");
        updateMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case updateMenuItemId:
                refresh();
                platformWithStateChangeAdapter.notifyDataSetChanged();
                break;
            case android.R.id.home:
                finish();
                break;
            default:
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    private Context getContext(){
        return this;
    }

    private void refresh(){
        ItemInfo itemInfo = new ItemInfo("Android02","I am Android!02",R.mipmap.ic_launcher,false);
        itemInfoList.add(itemInfo);
        itemInfo = new ItemInfo("Apple02","I am Apple!02",R.mipmap.ic_launcher,false);
        itemInfoList.add(itemInfo);
    }
}

 

 

ItemInfo.java
package com.example.administrator.listviewdemo;

/**
 * Created by Administrator on 2016/9/4.
 */
public class ItemInfo {
    private int img;
    private String title;
    private String info;
    private boolean selected;

    public ItemInfo(String title,String info,int img,boolean selected){
        this.title = title;
        this.info = info;
        this.img = img;
        this.selected = selected;
    }

    public int getImg() {
        return img;
    }

    public String getTitle() {
        return title;
    }

    public String getInfo() {
        return info;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setImg(int img) {
        this.img = img;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }
}

res/layout/activity_button_state_change_list.xml




    
    
    

        
        
        
    


ListView——CheckBox狀態屏幕滑動數據錯誤解決方法

之前我們小組在做一個項目,叫信號檢測,主要用於檢測運營商信號強度、用戶可以截屏並查看截屏記錄。其中用到ListView來展示截屏結果,我們的app為已經截屏的全部記錄的每一行數據(截屏)都提供一個CheckBox,用戶可以勾選當前截屏圖標刪除,先看一下整體的效果: \   在這裡也有個坑,當前我們截屏結果較多時(比如9張截屏),我們想刪除前3張,勾選了前3張圖標的CheckBox,結果第7、8、9張截屏的CheckBox也被勾選了,這當然不是我們希望的。
解決方法的思路:用一個map來保存每一行選中的狀態;我們聲明一個HashMap來保存每一行數據,除第一行數據外,其他每行數據都通過getTag()得到已經渲染好的view來重復渲染剩余行的數據。 首先,我們來看一下關鍵代碼:(具體代碼實現,可以下載查看我的Github項目:https://github.com/jscly/signal-detection)    
//通過聲明View,表示每一行數據都是一個view
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View view;
            ViewHolder holder = null;
            //待查看圖片的路徑
            final String currentImgFilePath = dirNameToSaveImg + "/" + imgList.get(position);

            if (map.get(position) == null) {
                LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = mInflater.inflate(R.layout.custom_listview_item, null);
                holder = new ViewHolder();
                holder.cbIsSelected = (CheckBox) view.findViewById(R.id.list_cbSelected);
                holder.ivImg = (ImageView) view.findViewById(R.id.list_ivImg);
                holder.tvImgName = (TextView) view.findViewById(R.id.list_tvImgName);
                holder.tvPrtScTime = (TextView) view.findViewById(R.id.list_tvPrtScTime);
                holder.ivNext = (ImageView) view.findViewById(R.id.list_ivNext);
                map.put(position, view);

                view.setTag(holder);
            } else {
                view = map.get(position);
                holder = (ViewHolder) view.getTag();
            }
            holder.cbIsSelected.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    CheckBox cb = (CheckBox) v;
                    //保存當前CheckBox的選中狀態
                    currentFileIsCheckedMap.put(currentImgFilePath, cb.isChecked());
                    if (cb.isChecked()) {
                        cb.setFocusable(true);
                        selectedImgList.add(currentImgFilePath);
                        //待刪除文件名及其ItemInfo
                        filePath_currentItemInfoMap.put(currentImgFilePath,listItemInfo.get(position));
                    }
                    else {
                        cb.setFocusable(true);
                        selectedImgList.remove(currentImgFilePath);
                        filePath_currentItemInfoMap.remove(currentImgFilePath);
                    }
                }
            });
            holder.ivNext.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ((ImageView)v).setFocusable(true);
                    openPrtSc(currentImgFilePath);
                }
            });

            holder.cbIsSelected.setChecked(currentFileIsCheckedMap.get(currentImgFilePath) != null ? currentFileIsCheckedMap.get(currentImgFilePath) : false);
            holder.ivImg.setImageBitmap(listItemInfo.get(position).getImgBitmap());
            holder.tvImgName.setText(listItemInfo.get(position).getImgName());
            holder.tvPrtScTime.setText(sdf.format(
                    new Date(
                            listItemInfo.get(position).getPrtScTime()
                    )
            ).toString());
            holder.ivNext.setImageResource(listItemInfo.get(position).getImgNextId());
            return view;
        }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved