【问题标题】:SearchView doesn't work with RecyclerView & SQLiteSearchView 不适用于 RecyclerView 和 SQLite
【发布时间】:2017-08-29 17:44:53
【问题描述】:

我有一个Fragment 和一个RecyclerView。用户输入数据,他们将存储在SQLite DataBase。我正在尝试 Search 中的 items 这个 RecyclerView 但它不起作用,

这是我的Fragment

public class FragmentOne extends Fragment {

private RecyclerView mDetailRecyclerView;
private DetailAdapter mAdapter;
private boolean mNumberVisible;
private SearchView sv;
private ArrayList<Detail> mDetails=new ArrayList<>();

private View view;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public View onCreateView(LayoutInflater inflater,
                         ViewGroup container,
                         Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_one_layout,
            container, false);

    mDetailRecyclerView = (RecyclerView) view.findViewById(R.id.detail_recycler_view);

    LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
    layoutManager.setReverseLayout(true); //This will reverse the data order but not scroll the RecyclerView to the last item
    layoutManager.setStackFromEnd(true); //For keeping data order same and simply scrolling the RecyclerView to the last item
    mDetailRecyclerView.setLayoutManager(layoutManager);

    if (savedInstanceState != null) {
        mNumberVisible =
                savedInstanceState.getBoolean(SAVED_NUMBER_VISIBLE);
    }

    sv = (SearchView) view.findViewById(R.id.sv);
    mAdapter = new DetailAdapter(mDetails);

    sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit (String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String query) {
            getDetailsSearch(query);
            return false;
        }
    });

    initViews();
    updateUI();
    return view;


}

@Override
public void onResume() {
    super.onResume();
    updateUI();
}



   @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(SAVED_NUMBER_VISIBLE, mNumberVisible);
    }

..
..
private class DetailHolder extends RecyclerView.ViewHolder
        implements View.OnClickListener, View.OnLongClickListener {
    private TextView mTitleTextView;
    //        private TextView mDateTextView;
    private Detail mDetail;
    private RatingBar mRatingBar;

    public DetailHolder(LayoutInflater inflater, ViewGroup parent) {
        super(inflater.inflate(R.layout.list_item_detail,
                parent, false));

        itemView.setOnClickListener(this);
        itemView.setOnLongClickListener(this);
        mTitleTextView = (TextView) itemView.findViewById(R.id.detail_title);
        mRatingBar = (RatingBar) itemView.findViewById(R.id.ratingBar);
    }

    public void bind(Detail detail) {
        mDetail = detail;
        mTitleTextView.setText(mDetail.getTitle());
        mRatingBar.setRating(mDetail.getRate());
    }

    @Override
    public void onClick(View view) {
        Intent intent = DetailPagerActivity.newIntent(getActivity(),
                mDetail.getId());
        startActivity(intent);
    }
}


private class DetailAdapter extends RecyclerView.Adapter<DetailHolder> {
    private List<Detail> mDetails;
    private Detail mDetail;

    public DetailAdapter(List<Detail> details) {
        mDetails = details;
    }

    @Override
    public DetailHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
        return new DetailHolder(layoutInflater, parent);
    }

    @Override
    public void onBindViewHolder(DetailHolder holder, int position) {
        Detail detail = mDetails.get(position);
        holder.bind(detail);
    }

    @Override
    public int getItemCount() {
        return mDetails.size();
    }

    public void setDetails(final List<Detail> details) {
        mDetails = details;
    }

    ..
    ..

}

public void initViews(){
    mDetailRecyclerView.setAdapter(mAdapter);
    initSwipe();
}

..
..

private void getDetailsSearch (String searchTerm) {
    mDetails.clear();

    DBAdapter db = new DBAdapter(getActivity());
    db.openDB();
    Detail p = null;
    Cursor c = db.retrieve(searchTerm);

    while (c.moveToNext()) {
        String title = c.getString(2);

        p = new Detail();
        p.setTitle(title);

        mDetails.add(p);
    }

    db.closeDB();
    mDetailRecyclerView.setAdapter(mAdapter);
}
}

这是我的Database Adapter

public class DBAdapter {
    Context c;
    SQLiteDatabase db;
    DetailBaseHelper helper;

    public DBAdapter (Context c) {
        this.c = c;
        helper = new DetailBaseHelper(c);
    }

    public void openDB() {
        try {
            db = helper.getWritableDatabase();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void closeDB() {
        try {
            helper.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public Cursor retrieve (String searchTerm) {
        String[] columns = {
            "_id",
            "uuid",
            "title",
            "des",
            "date",
            "rate"
        Cursor c = null;

        if (searchTerm != null && searchTerm.length()>0) {
            String sql ="SELECT * FROM " +DetailDbSchema.DetailTable.NAME+
                    " WHERE "+DetailDbSchema.DetailTable.Cols.TITLE+
                    " LIKE '%"+searchTerm+"%'";
            c = db.rawQuery(sql, null);
            return c;
        }

        c = db.query(DetailDbSchema.DetailTable.NAME, columns,
                null, null, null, null, null);
        return c;
    }
}

这里是DataBase Helper:

public class DetailBaseHelper extends SQLiteOpenHelper{
    private static final int VERSION = 1;
    private static final String DATABASE_NAME = "detailBase.db";

    public DetailBaseHelper (Context context) {
        super(context, DATABASE_NAME, null, VERSION);
    }

    @Override
    public void onCreate (SQLiteDatabase db) {
        db.execSQL("create table " + DetailTable.NAME +
                "(" +
                " _id integer primary key autoincrement," +
                DetailTable.Cols.UUID + ", " +
                DetailTable.Cols.TITLE + ", " +
                DetailTable.Cols.DES + ", " +
                DetailTable.Cols.DATE + ", " +
                DetailTable.Cols.RATE +
                ")"
        );
    }

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

here 是我用来做这个的教程, 如果你有任何帮助我的想法,我将不胜感激。

【问题讨论】:

    标签: android sqlite android-recyclerview searchview


    【解决方案1】:

    我认为主要问题在于您正在更改适配器,但新适配器从未被结果数据修改,并且您必须通知您的回收商数据集已更改。所以

    private void getDetailsSearch (String searchTerm) {
    mDetails.clear();
    /// the loop wiith the cursor
    
    /// change the dataset
    mAdapter = new DetailAdapter(mDetails);
    
    mDetailRecyclerView.setAdapter(mAdapter);
    
    /// tell the recycler there is a different data to display
    mDetailRecyclerView.notifyDataSetChanged();
    
    }
    

    【讨论】:

    • 是的,你是对的,我按照你说的做了 但我使用 mDetailRecyclerView.notifyDataSetChanged(); 而不是 mAdapter.notifyDataSetChanged(); 并且它有效,但现在它显示了我的错误答案搜索和numbers 而不是string
    • 当然是adapter.notifyDataSetChanged();对不起!!!好吧,您现在向前迈进了一步,我的建议是:调试 DBAdapter 的检索(字符串)方法并查看是否按应有的方式进行,因为光标可能没有您想要的,或者问题出在某个地方否则
    • 你是对的,但我无法解决问题,因为 uci 在我的 Database Adapter 中有 05 列,但我无法在 getDetailsSearch 中定义它们,我认为我的问题就在那里。 . 有什么想法吗?
    • 好吧,我相信你应该编写不同的 sqlite 方法来做不同的事情,这给了你更多的灵活性,因为只有 retrieve() 方法看起来很灵活,但实际上很相关,所以你应该有不同的方法在您想要的不同场景中,从数据库中获取您想要的信息。这还需要您编写不同的查询以从数据库中提取该信息。
    • 嗯,我用view pager 来显示items,我认为问题可能是因为从这个片段到另一个片段的不同ID..我会按照你说的做))
    猜你喜欢
    • 2018-10-08
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    相关资源
    最近更新 更多