0

嗨,我正在使用具有自定义列表视图的 android 应用程序。listview 中的项目大约 3000。我的问题是在滚动加载项目后会导致 outOfMemory 错误。

我正在使用基本适配器,每个项目都有一个复选框和四个文本视图。

这是我的代码。请让我知道解决方案。

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;
        }

    }


}

我也尝试过使用 View Holder,但加载速度仍然很慢。请告诉解决方案如何解决这个问题。

4

1 回答 1

0
  1. 你需要重用view参数View getView(final int position, Vie view, ViewGroup parent),如果它不为空,那么你不需要再次膨胀。
  2. 使用 ViewHolder 模式;
  3. loop for (int dd = 0; dd < arrayListFirstName.size(); dd++)从 getView中移除;
  4. 尝试简化列表项的布局;
  5. 似乎arrayListFirstName.size()可以简化(例如使用一些变量来避免size()调用)
  6. 进行分析以确切地知道什么是减速你滚动(这可能就足够了 profike only getView()


此外,请查看来自 Google I/O的此视频,了解有关如何以正确方式制作 ListViews 的更多详细信息。

于 2013-03-05T08:46:28.360 回答