1. 程式人生 > >ViewHolder模式獲取控制元件空指標異常

ViewHolder模式獲取控制元件空指標異常

在用ListView做開發的時候需要整合BaseAdapter類,複寫其getView方法,這個想必大家都是知道的。今天在除錯的時候遇到一個很折騰人的問題,在ViewHolder模式是用以下方式給TextView控制元件賦值時報空指標異常:


import engina.AppInfoProvider;
/**
 * Created by lin on 2016/9/9.
 */
public class AppManagerActivity extends Activity {
    private TextView tv_avail_rom;
    private TextView tv_avail_sd
; private ListView lv_app_manager; private LinearLayout ll_loading; /** * 所有的應用程式包資訊 */ private List<AppInfo> appInfos; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_app_manager); tv_avail_rom
= (TextView) findViewById(R.id.tv_avail_rom); tv_avail_sd = (TextView) findViewById(R.id.tv_avail_sd); long sdsize = getAvailSpace(Environment.getExternalStorageDirectory().getAbsolutePath()); long romsize = getAvailSpace(Environment.getDataDirectory().getAbsolutePath()); tv_avail_sd
.setText("SD卡可用空間:" + Formatter.formatFileSize(this, sdsize)); tv_avail_rom.setText("記憶體可用空間" + Formatter.formatFileSize(this, romsize)); lv_app_manager = (ListView) findViewById((R.id.lv_app_manager)); ll_loading = (LinearLayout) findViewById(R.id.ll_loading); ll_loading.setVisibility(View.VISIBLE); new Thread() { public void run() { appInfos = AppInfoProvider.getAppInfos(AppManagerActivity.this); //載入listview的資料介面卡 runOnUiThread(new Runnable() { @Override public void run() { lv_app_manager.setAdapter(new AppMangerAdapter()); ll_loading.setVisibility(View.INVISIBLE); } }); } ; }.start(); } static class ViewHolder { TextView tv_name; TextView tv_location; ImageView iv_icon; } private class AppMangerAdapter extends BaseAdapter { @Override public int getCount() { return appInfos.size(); } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View convertView, ViewGroup viewGroup) { // TextView tv=new TextView(getApplicationContext()); // tv.setText(appInfos.get(i).toString()); // return tv; View view; ViewHolder holder; if (convertView != null) { view = convertView; holder = (ViewHolder) view.getTag(); } else { view = View.inflate(getApplicationContext(),R.layout.list_item_appinfo,null); holder = new ViewHolder(); holder.iv_icon = (ImageView) view.findViewById(R.id.iv_app_icon); holder.tv_location = (TextView)findViewById(R.id.tv_app_location);//此處出現空指標 holder.tv_name = (TextView)findViewById(R.id.tv_app_name);//此處出現空指標 view.setTag(holder); } AppInfo appInfo = appInfos.get(i); holder.iv_icon.setImageDrawable(appInfo.getIcon()); System.out.println("應用名稱"+appInfo.getName()); holder.tv_name.setText(appInfo.getName()); if(appInfo.isInRom()){ holder.tv_location.setText("手機記憶體"); }else { holder.tv_location.setText("外部儲存"); } return view; } } /** * 獲取某個目錄的可用空間 * * @param path * @return */ private long getAvailSpace(String path) { StatFs statf = new StatFs(path); statf.getBlockCount();//獲取分割槽的個數 long size = statf.getBlockSize();//獲取分割槽的大小 long count = statf.getAvailableBlocks();//獲取可用區塊的個數 return size * count; } }

根據現象,百度了一下…… 結果,原來原因就少添加了一個View。出現指標那裡修改成下面程式碼就可以了

holder.iv_icon = (ImageView) view.findViewById(R.id.iv_app_icon);
holder.tv_location = (TextView)view.findViewById(R.id.tv_app_location);
holder.tv_name = (TextView)view.findViewById(R.id.tv_app_name);

參考部落格:http://blog.csdn.net/cheer_zhang/article/details/38057567