使用SQLite数据库加载更多的回收站视图

时间:2017-03-14 18:05:06

标签: android sqlite android-recyclerview

有一个活动中有多个片段。

第一个片段是WriteFragment,其中有两个编辑文本字段,一个插入按钮和一个读取按钮。

单击“插入”按钮可将编辑文本字段中显示的条目插入SQLite数据库。

单击“读取”按钮可从SQLite数据库中读取数据并在回收站视图中显示。

但是,数据应以最多4个显示。

当用户到达底部时,它应该显示2秒的循环进度条,之后它应该显示另一组最多有4个数据。

如果剩余数据小于4,则应立即显示。

现在,问题是: -

读取调用每次都从头开始读取数据,即使我每次都在更改start,end和slot(束,集)值。

假设有4个数据,我正在调用read_fragment。它会正确显示前4个数据。现在我回到write_fragment并做一些插入操作。现在,这次当我调用read_fragment时,它最初显示前4个数据,然后在循环进度条加载2秒后,它再次显示这4个数据,然后它将显示其余的数据。这个过程重复了!

我无法理解为什么它会加载相同的数据?!为什么loadMoreData()方法没有按预期工作?!

以下是我的DBHelper类:_

public class DBHelper extends SQLiteOpenHelper {

private static String MyDb = "MyDb.db";
private static String MyTable = "MyTable";
private static String id = "id";
private static String fname = "fname";
private static String lname = "lname";
private static int version = 1;
private static final ArrayList<User> list = new ArrayList<>();

private static final String sql =  "create table " + MyTable + " ( " + id + " integer primary key autoincrement, "

                                                   + fname + " text, "

                                                   + lname + " text )";

DBHelper(Context context) {
    super(context, MyDb, null, version);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL(sql);
}

void insert (User user) {

    SQLiteDatabase sqLiteDatabase = getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(fname, user.getFname());
    contentValues.put(lname, user.getLname());
    sqLiteDatabase.insert(MyTable, id, contentValues);
    sqLiteDatabase.close();
}

ArrayList<User> read () {

    /*We are required to have readable database to read data*/

    SQLiteDatabase sqLiteDatabase = getReadableDatabase();

    /*Columns that we want to read*/

    String [] columns = {id, fname, lname};

    /*Query to read database*/

    Cursor cursor = sqLiteDatabase.query(MyTable, columns, null, null, null, null, null);

    /*cursor.move(cursorPosition);*/ // Move the cursor by a relative amount, forward or backward, from the current position.

    /*cursor.moveToPosition(cursorPosition);*/ // Move the cursor to an absolute position.

    while (cursor.moveToNext()){

        int id = cursor.getInt(0);
        String fname = cursor.getString(1);
        String lname = cursor.getString(2);

        User user = new User();
        user.setId(id);
        user.setFname(fname);
        user.setLname(lname);
        list.add(user);
    }

    return list;
}

public void deleteItem(int position) {

    //Open the database

    SQLiteDatabase database = this.getWritableDatabase();

    //Execute sql query to remove from database

    //NOTE: When removing by String in SQL, value must be enclosed with ''

    /*Following is the query way to delete an item. We can also perform, call delete function on our database as well*/

    database.execSQL("DELETE FROM " + MyTable + " WHERE " + id + "= '" + position + "'");

    //Close the database

    database.close();
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}

}

以下是我的read_fragment类:_

public class ReadFragment extends android.app.Fragment {

RecyclerView recyclerView;

RvAdapter rvAdapter;

ArrayList<User> ulist = new ArrayList<>();

ArrayList<User> partialList = new ArrayList<>();

User udata = new User();

public ReadFragment() {

    // Required empty public constructor
}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

                         Bundle savedInstanceState) {

    // Inflate the layout for this fragment

    View v = inflater.inflate(R.layout.fragment_read, container, false);

    recyclerView = (RecyclerView) v.findViewById(R.id.recyclerView);

    DBHelper dbHelper = new DBHelper(getActivity());

    ulist = dbHelper.read();

    loadMoreData();

    rvAdapter = new RvAdapter(partialList, recyclerView, getActivity());

    recyclerView.setAdapter(rvAdapter);

    rvAdapter.notifyDataSetChanged();

    rvAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {

        @Override

        public void onLoadMore() {

            Log.e("onLoadMore", "Load More");

            partialList.add(null); // Adding null will give ItemViewType as cyclic progressBar to viewHolder

            rvAdapter.notifyItemInserted(partialList.size() - 1);

            //Load more data for reyclerview

            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {

                    Log.e("run", "Load More 2");

                    //Remove loading item

                    partialList.remove(partialList.size() - 1); // This will remove cyclic progressBar

                    rvAdapter.notifyItemRemoved(partialList.size());

                    //Load data

                    loadMoreData();

                    rvAdapter.notifyDataSetChanged();

                    rvAdapter.setLoaded();

                }

            }, 2000);
        }
    });

    return v;
}

public void loadMoreData() {

    int end = ulist.size() - 1;

    int start = partialList.size();

    int bunch = start + 3;

    if (bunch <= end) {

        for (int i = start; i <= bunch; i++) {

            udata = ulist.get(i);

            partialList.add(udata);
        }

    } else {

        for (int i = start; i <= end; i++) {

            udata = ulist.get(i);

            partialList.add(udata);
        }
    }

}

}

以下是我的RecyclerView适配器类:_

class RvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private final int VIEW_TYPE_ITEM = 0;

private final int VIEW_TYPE_LOADING = 1;

private boolean isLoading;

private int visibleThreshold = 5;

private int lastVisibleItem, totalItemCount;

private ArrayList<User> ulist;

private OnLoadMoreListener mOnLoadMoreListener;

RvAdapter(ArrayList<User> ulist, RecyclerView recyclerView, Activity activity) {

    this.ulist = ulist;

    final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(activity);

    recyclerView.setLayoutManager(linearLayoutManager);

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

        @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

            super.onScrolled(recyclerView, dx, dy);

            totalItemCount = linearLayoutManager.getItemCount();

            lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();

            if (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {

                if (mOnLoadMoreListener != null) {

                    mOnLoadMoreListener.onLoadMore();
                }

                isLoading = true;
            }
        }
    });
}

void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {

    this.mOnLoadMoreListener = mOnLoadMoreListener;
}

private static class ItemViewHolder extends RecyclerView.ViewHolder {

    private TextView tv_id, tv_fname, tv_lname;

    private ImageButton deleteButton;

    private ItemViewHolder(View itemView) {

        super(itemView);

        tv_id = (TextView) itemView.findViewById(R.id.tv_id);

        tv_fname = (TextView) itemView.findViewById(R.id.tv_fname);

        tv_lname = (TextView) itemView.findViewById(R.id.tv_lname);

        deleteButton = (ImageButton) itemView.findViewById(R.id.btn_delete);
    }
}

private static class LoadingViewHolder extends RecyclerView.ViewHolder {

    private ProgressBar progressBar;

    private LoadingViewHolder(View itemView) {

        super(itemView);

        progressBar = (ProgressBar) itemView.findViewById(R.id.progressBar);
    }
}

@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    if (viewType == VIEW_TYPE_ITEM) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.model, parent, false);

        return new ItemViewHolder(view);

    } else if (viewType == VIEW_TYPE_LOADING) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.loading_layout, parent, false);

        return new LoadingViewHolder(view);
    }

    return null;
}

@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    if (holder instanceof ItemViewHolder) {

        User user = ulist.get(position);

        ItemViewHolder userViewHolder = (ItemViewHolder) holder;

        userViewHolder.tv_id.setText(String.valueOf(user.getId()));

        userViewHolder.tv_fname.setText(user.getFname());

        userViewHolder.tv_lname.setText(user.getLname());

    } else if (holder instanceof LoadingViewHolder) {

        LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;

        loadingViewHolder.progressBar.setIndeterminate(true);
    }
}

@Override public int getItemCount() {

    return ulist == null ? 0 : ulist.size();
}

@Override public int getItemViewType(int position) {

    return ulist.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}

void setLoaded() {

    isLoading = false;
}

}

我也尝试过跟随loadMoreData()的逻辑:_

start = partialList.size();

    for (int i = start; i <= start + 3; i++) {

        if (ulist.size() > slot) {

            slot = i + 1;

            udata = ulist.get(i);

            partialList.add(udata);
        }
    }

    start = partialList.size();

但是,如果没有运气,我仍然会在每次滚动事件之后从头开始获取列表!!!

任何帮助将不胜感激。提前感谢您提供宝贵的时间。

2 个答案:

答案 0 :(得分:0)

您可以在此链接中查看Load More RecyclerView和Bottom ProgressBar Load More RecyclerView and Bottom ProgressBar

答案 1 :(得分:0)

我多次获得相同数据的原因是最终的ArrayList。所以,它就像是,final关键字设置固定值的变量,但是当我以某种方式修改该变量时,它每次给我新的列表,显然会包含所有值,包括新的值。所以,它就像是每次都在创建ArrayList的新对象。但是,如果有人能够确认我已经完成的内容并以清晰和更好的方式解释幕后的过程,我们将不胜感激。