2013-03-05 54 views
0

嗨我正在使用具有自定義列表視圖的android應用程序。在列表視圖中的項目大約3000.我的問題是加載項目後滾動它使內存錯誤。使用基本適配器的自定義列表視圖在Android中無法快速滾動

我正在使用Base Adapter,每個項目有一個複選框和四個文本視圖。

這是我的代碼。請讓我知道解決方案。

public class GuestListAdapter extends BaseAdapter implements OnClickListener { 
    private String strExe; 
    AlertDialog.Builder builder; 
    String sId; 
    String sCheckIn; 
    String strCheckInResponse; 

    Context context; 
    private ArrayList<String> arrayListId; 
    private ArrayList<String> arrayListFirstName; 
    private ArrayList<String> arrayListLastName; 
    private ArrayList<String> arrayListGuests; 
    private ArrayList<String> arrayCustomOne; 
    private ArrayList<String> arTempId; 
    public static ArrayList<Boolean> chickinlist; 

    public static ArrayList<Integer> arrCheckedItems; 
    public static ArrayList<Integer> arrUnCheckedItems; 
    Button btnInfo; 
    private SQLiteAdapter mySqliteAdapter; 
    private GuestListScreen myGuestList; 
    private RelativeLayout views; 
    private String strAlertValue; 

    // private AlertDialog alertDialog = null; 

    private ArrayList<Boolean> checks = new ArrayList<Boolean>(); 

    public GuestListAdapter(Context mcontext, ArrayList<String> arrListid, 
      ArrayList<String> arrListFN, ArrayList<String> arrListLN, 
      ArrayList<String> arrListGuest, ArrayList<String> arrTiketID, 
      ArrayList<String> arrCustOne, ArrayList<Boolean> chicklist) { 

     clearAdapter(); 

     arrayListId = new ArrayList<String>(); 
     arrayListFirstName = new ArrayList<String>(); 
     arrayListLastName = new ArrayList<String>(); 
     arrayListGuests = new ArrayList<String>(); 
     arrayCustomOne = new ArrayList<String>(); 
     arTempId = new ArrayList<String>(); 
     chickinlist = new ArrayList<Boolean>(); 
     arrCheckedItems = new ArrayList<Integer>(); 
     arrUnCheckedItems = new ArrayList<Integer>(); 

     arrayListId = arrListid; 
     arrayListFirstName = arrListFN; 
     arrayListLastName = arrListLN; 
     arrayListGuests = arrListGuest; 
     arrayCustomOne = arrCustOne; 
     arTempId = arrTiketID; 
     chickinlist = chicklist; 

     context = mcontext; 
     mySqliteAdapter = new SQLiteAdapter(context); 

     for (int i = 0; i < arrayListFirstName.size(); i++) { 
      checks.add(i, false); 
     } 
    } 

    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 

     return arrayListFirstName.size(); 

    } 

    @Override 
    public Object getItem(int position) { 
     // TODO Auto-generated method stub 

     return arrayListFirstName.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     // TODO Auto-generated method stub 
     return position; 
    } 

    @Override 
    public View getView(final int position, View view, ViewGroup parent) { 

     final int pos = position; 
     views = null; 
     LayoutInflater layoutInflator = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     views = (RelativeLayout) layoutInflator.inflate(
       R.layout.guest_list_item, null); 

     final CheckBox chk = (CheckBox) views.getChildAt(0); 
     // Log.d("", "CheckBox Pos "+position); 
     chk.setId(position); 

     TextView txtView = (TextView) views.getChildAt(1); 

     TextView txtView2 = (TextView) views.getChildAt(2); 
     TextView txtView3 = (TextView) views.getChildAt(3); 

     final TextView txtView4 = (TextView) views.getChildAt(4); 
     TextView txtView5 = (TextView) views.getChildAt(6); 
     txtView5.setId(position); 

     // Log.d("", "Button Pos "+position); 
     txtView4.setId(position); 

     txtView4.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Intent intent = new Intent(context, InfoScreen.class); 
       intent.putExtra("IDVALUE", arTempId.get(txtView4.getId())); 
       intent.putExtra("IDVALUE", arrayListId.get(position)); 

       intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); 
       context.startActivity(intent); 

      } 
     }); 


     for (int dd = 0; dd < arrayListFirstName.size(); dd++) { 
      if (position == dd) { 
       // Log.d("", "Passsing arr size " + chickinlist.size()); 
       Boolean result = chickinlist.get(position); 
       // Log.d("", "After " + result); 
       if (result == true) { 
        chk.setChecked(true); 
        arrCheckedItems.add(position); 
        views.setBackgroundResource(R.drawable.list_item_checked); 

       } else { 
        chk.setChecked(false); 
        arrUnCheckedItems.add(position); 
        views.setBackgroundResource(R.drawable.list_item_unchecked); 

       } 

       txtView.setText(arrayListFirstName.get(position)); 
       txtView2.setText(arrayListLastName.get(position)); 
       txtView3.setText("(" + arrayListGuests.get(position) + ")"); 
       if (arrayCustomOne.get(position).equalsIgnoreCase("0") 
         || arrayCustomOne.get(position).equalsIgnoreCase(null) 
         || arrayCustomOne.get(position).equalsIgnoreCase(
           "(null)")) { 
        txtView5.setText(""); 
       } else { 
        txtView5.setText(arrayCustomOne.get(position)); 
       } 

      } 

     } 

     chk.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

      @Override 
      public void onCheckedChanged(CompoundButton buttonView, 
        boolean isChecked) { 
       mySqliteAdapter.openToWrite(); 

       sId = arrayListId.get(chk.getId()); 
       // Log.d("Adapter", 
       // "Checked Temp Id "+arTempId.get(chk.getId())); 


       if (isChecked) { 

        chk.setChecked(true); 
        arrCheckedItems.add(position); 
        strAlertValue = "1"; 
        sCheckIn = "1"; 
        strExe = "update ticket_details set checkin_status=1 where tempid=" 
          + arTempId.get(chk.getId()); 
        mySqliteAdapter.executeCheckQurey(strExe); 
        if (Util.getInstance(context).isTabletDevice()) { 
         buttonView 
           .setBackgroundResource(R.drawable.tablet_list_item_check); 
         Log.e("Tablet", "Tablet Checked "); 
        } else { 
         buttonView 
           .setBackgroundResource(R.drawable.list_item_checked); 
         Log.e("Device", "Device Checked "); 
        } 

        new CheckInUpdate().execute(); 
        AlertDialog.Builder builder = new AlertDialog.Builder(
          context); 
        builder.create(); 
        builder.setMessage(arrayListFirstName.get(chk.getId()) 
          + " " + arrayListLastName.get(chk.getId()) 
          + " has been checked in."); 
        builder.setPositiveButton("Ok", 
          new DialogInterface.OnClickListener() { 

           @Override 
           public void onClick(DialogInterface dialog, 
             int which) { 


            Intent intentNavGuestList = new Intent(
              context, GuestListScreen.class); 
            intentNavGuestList 
              .addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); 
            context.startActivity(intentNavGuestList); 

            dialog.dismiss(); 

           } 

          }).show(); 

        // Log.d("", "ID = " + buttonView.getId()); 

       } 
       if (!isChecked) { 

        sCheckIn = "0"; 
        strAlertValue = "0"; 


        strExe = "update ticket_details set checkin_status=0 where tempid=" 
          + arTempId.get(chk.getId()); 

        mySqliteAdapter.executeCheckQurey(strExe); 

        if (Util.getInstance(context).isTabletDevice()) { 
         buttonView 
           .setBackgroundResource(R.drawable.tablet_list_item_uncheck); 
         Log.e("Tablet", "Tablet UnChecked "); 
        } else { 
         buttonView 
           .setBackgroundResource(R.drawable.list_item_unchecked); 
         Log.e("Device", "Device UnChecked "); 
        } 
        new CheckInUpdate().execute(); 


        Intent intentNavGuestList = new Intent(context, 
          GuestListScreen.class); 
        intentNavGuestList 
          .addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); 
        context.startActivity(intentNavGuestList); 



       } 

      } 
     }); 

     return views; 

    } 

    @Override 
    public void notifyDataSetChanged() { 
     // TODO Auto-generated method stub 

     super.notifyDataSetChanged(); 
    } 

    @Override 
    public void onClick(View view) { 
     // TODO Auto-generated method stub 
     Integer index = (Integer) view.getTag(); 
     boolean state = checks.get(index.intValue()); 

     checks.set(index.intValue(), !state); 
    } 


    public void clearAdapter() { 
     if (arrayListFirstName != null) { 

      arrayListFirstName.clear(); 
      arrayListId.clear(); 
      arrayListId = null; 
      arrayListFirstName = null; 
      arrayListLastName.clear(); 
      arrayListLastName = null; 
      arrayListGuests.clear(); 
      arrayListGuests = null; 
      arrayCustomOne.clear(); 
      arrayCustomOne = null; 
      arTempId.clear(); 
      arTempId = null; 
      chickinlist.clear(); 
      chickinlist = null; 
      arrCheckedItems.clear(); 
      arrCheckedItems = null; 
      arrUnCheckedItems.clear(); 
      arrUnCheckedItems = null; 
     } 

    } 


} 

我也試過查看持有人,但仍然加載緩慢。請告訴解決方案如何解決這個問題。

回答

0
  1. 你需要從View getView(final int position, Vie view, ViewGroup parent)重用view paremeter,如果它不爲空,則不需要再次膨脹。
  2. 使用ViewHolder模式;
  3. 刪除loop for (int dd = 0; dd < arrayListFirstName.size(); dd++) from getView;
  4. 嘗試簡化列表項目的佈局;
  5. 似乎arrayListFirstName.size()可以簡化(如用一些變量來避免size()呼叫)
  6. profiling爲了確切地知道什麼是緩慢起伏你滾動(這可能足以profike僅getView()


此外,請查看this video from Google I/O瞭解如何以正確方式製作ListView的更多詳細信息。

+0

感謝您的快速響應,我已經嘗試如果(視圖== null)膨脹其他視圖=(相對)views.getTag(); ...但仍然加載減慢滾動 – Dhamodharan 2013-03-05 08:51:14

+0

它肯定應該比沒有它快得多。另外,ViewHolder應該加速滾動。但是,由於非常複雜的列表項目,它可能仍然很慢。你有沒有嘗試分析http://developer.android.com/tools/debugging/debugging-tracing.html以確定根本原因?可能它不是適配器? – sandrstar 2013-03-05 08:52:26

相關問題