在包含超过 30,000 个项目的可扩展列表视图中延迟加载

lazy load in an expandable list view with over 30 thousand items

  1. 我正在寻找一种解决方案来处理 30,000 个 GroupItem,在可扩展列表视图中使用无限滚动或延迟加载?如何将其实现到 MyCustomAdapter 中?

项目从本地 .txt 文件加载到数组中并填充到可扩展列表中。

  1. 如何处理尽可能多的项目的过滤器,因为在每次按键时应用程序都会冻结,具体取决于我使用的设备。

这是我的自定义适配器:

public class MyCustomAdapter extends BaseExpandableListAdapter {
    private LayoutInflater inflater;
    private ArrayList<Parent> mParent;
    private static final String TAG = "MyCustomAdapter: ";
    private static final boolean DEBUG = true;
    private ArrayList<Parent> arraylist;
    Context aContext;

    public MyCustomAdapter(Context context, ArrayList<Parent> parent){
        mParent = parent;
        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        this.arraylist = new ArrayList<>();
        this.arraylist.addAll(parent);


    }


    @Override
    //counts the number of group/parent items so the list knows how many times calls getGroupView() method
    public int getGroupCount() {
        return mParent.size();
    }

    @Override
    //counts the number of children items so the list knows how many times calls getChildView() method
    public int getChildrenCount(int i) {
        return mParent.get(i).getArrayChildren().size();
    }

    @Override
    //gets the title of each parent/group
    public Object getGroup(int i) {
        return mParent.get(i).getTitle();
    }

    public Object getGroupName(int i){
        return mParent.get(i).getName();
    }

    @Override
    //gets the name of each item
    public Object getChild(int i, int i1) {
        return mParent.get(i).getArrayChildren().get(i1);
    }

    @Override
    public long getGroupId(int i) {
        return i;
    }

    @Override
    public long getChildId(int i, int i1) {
        return i1;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    //in this method you must set the text to see the parent/group on the list
    public View getGroupView(int groupPosition, boolean isExpanded, View view, ViewGroup viewGroup) {

        ViewHolder holder = new ViewHolder();
        holder.groupPosition = groupPosition;

        if (view == null) {

            view = inflater.inflate(R.layout.list_item_parent, viewGroup, false);
        }

        Parent item = mParent.get(groupPosition);
        //if (DEBUG)Log.e(TAG, "Selected text: " + (item.getName()));
        TextView nameText = (TextView) view.findViewById(R.id.nameValue);
        nameText.setText(item.getName());



        TextView countryLanguageGenreText = (TextView) view.findViewById((R.id.countryLanguageGenre));
        countryLanguageGenreText.setText(item.getCountryLanguageGenre());



        view.setTag(holder);

        //return the entire view
        return view;
    }

    @Override
    //in this method you must set the text to see the children on the list
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View view, ViewGroup viewGroup) {

        ViewHolder holder = new ViewHolder();
        holder.childPosition = childPosition;
        holder.groupPosition = groupPosition;

        if (view == null) {
            view = inflater.inflate(R.layout.list_item_child, viewGroup, false);
        }

        TextView textView = (TextView) view.findViewById(R.id.list_item_text_child);
        textView.setText(mParent.get(groupPosition).getArrayChildren().get(childPosition));


        view.setTag(holder);

        //return the entire view
        return view;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return true;
    }

    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        /* used to make the notifyDataSetChanged() method work */
        super.registerDataSetObserver(observer);
    }



    protected class ViewHolder {
        protected int childPosition;
        protected int groupPosition;
        protected Button button;
    }


    // Filter Class
    public void filter(String charText) {
        charText = charText.toLowerCase(Locale.getDefault());
        mParent.clear();
        if (charText.length() == 0) {
            mParent.addAll(arraylist);
        }
        else
        {
            for (Parent wp : arraylist)
            {
                if (wp.getSearchString().toLowerCase(Locale.getDefault()).contains(charText))
                {
                    mParent.add(wp);
                }
            }
        }
        notifyDataSetChanged();
    }
}

列表视图的一个特点是它只对可见的列表项进行回收和重新创建。问题不在于列表视图中项目的长度。就是读取文件效率低下。

我建议您使用数据库支持的设计,这将使应用程序更加稳定,并且您可以轻松地使过滤器工作。

我同意@Diyoda 关于将文本文件中的数据导入数据库支持的设计的观点。然后可能会看看通过 droidQuery 做 ajax 之类的请求。 Can ajax call be done in Android?

http://phil-brown.github.io/droidQuery/

当用户向下滚动时,您会执行异步请求以获取更多数据。您像使用 jQuery ajax 一样轮询 URL,然后将一个参数传递给您的适配器,它从您的数据库中获取下一组数据。