I am using RecyclerView
to list some text and SearchView
to search through the list and when the user clicks on a text in the list it opens a new activity specific that text. Before I used SearchView
I just had my list of text and used switch statements if the user clicks on first line it opens first activity ect...
Now with the SearchView
when you search for something at the bottom the result pops to the top of the list so the switch statement opens the first acitvity which is wrong.
So yea im stuck on how to open the correct activity for the correct text in the list when the user searches. Can someone help me with an example
MainFragment.java
public class MainFragment extends Fragment implements SearchView.OnQueryTextListener {
private static final String[] DUMMYTEXT = new String[]{
"Text One ",
"Text Two",
"Text Three",
"Text Four"
};
private RecyclerView mRecyclerView;
private Adapter mAdapter;
private List<Model> mModels;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_main, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mModels = new ArrayList<>();
for (String dummyText : DUMMYTEXT) {
mModels.add(new Model(dummyText));
}
mAdapter = new Adapter(getActivity(), mModels);
mRecyclerView.setAdapter(mAdapter);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onQueryTextChange(String query) {
final List<Model> filteredModelList = filter(mModels, query);
mAdapter.animateTo(filteredModelList);
mRecyclerView.scrollToPosition(0);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
private List<Model> filter(List<Model> models, String query) {
query = query.toLowerCase();
final List<Model> filteredModelList = new ArrayList<>();
for (Model model : models) {
final String text = model.getText().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
}
ViewHolder.java
public class ViewHolder extends RecyclerView.ViewHolder {
private final TextView tvText;
private final Context context;
public ViewHolder(final View itemView) {
super(itemView);
context = itemView.getContext();
tvText = (TextView) itemView.findViewById(R.id.tvText);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = null;
switch (getAdapterPosition()) {
case 0:
intent = new Intent(context, FirstActivity.class);
break;
case 1:
intent = new Intent(context, SecondActivity.class);
break;
case 2:
intent = new Intent(context, ThirdActivity.class);
break;
case 3:
intent = new Intent(context, FourthActivity.class);
default:
break;
}
context.startActivity(intent);
}
});
}
public void bind(Model model) {
tvText.setText(model.getText());
}
}
Model.java
public class Model {
private final String mText;
public Model(String text) {
mText = text;
}
public String getText() {
return mText;
}
}
Adapter.java
public class Adapter extends RecyclerView.Adapter<ViewHolder> {
private final LayoutInflater mInflater;
private final List<Model> mModels;
public Adapter(Context context, List<Model> models) {
mInflater = LayoutInflater.from(context);
mModels = new ArrayList<>(models);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View itemView = mInflater.inflate(R.layout.text_items, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Model model = mModels.get(position);
holder.bind(model);
}
@Override
public int getItemCount() {
return mModels.size();
}
public void animateTo(List<Model> models) {
applyAndAnimateRemovals(models);
applyAndAnimateAdditions(models);
applyAndAnimateMovedItems(models);
}
private void applyAndAnimateRemovals(List<Model> newModels) {
for (int i = mModels.size() - 1; i >= 0; i--) {
final Model model = mModels.get(i);
if (!newModels.contains(model)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(List<Model> newModels) {
for (int i = 0, count = newModels.size(); i < count; i++) {
final Model model = newModels.get(i);
if (!mModels.contains(model)) {
addItem(i, model);
}
}
}
private void applyAndAnimateMovedItems(List<Model> newModels) {
for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
final Model model = newModels.get(toPosition);
final int fromPosition = mModels.indexOf(model);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
public Model removeItem(int position) {
final Model model = mModels.remove(position);
notifyItemRemoved(position);
return model;
}
public void addItem(int position, Model model) {
mModels.add(position, model);
notifyItemInserted(position);
}
public void moveItem(int fromPosition, int toPosition) {
final Model model = mModels.remove(fromPosition);
mModels.add(toPosition, model);
notifyItemMoved(fromPosition, toPosition);
}
}
The problem here relates to data binding. Your model
is not aware of what's expected of it in the event its chosen (clicked). The example below may seem convoluted, but its meant to highlight the issue.
Let's change your model class:
public class Model {
private final String mText;
private Class mLaunchClass;
public Model(String text, Class launchClass) {
mText = text;
mLaunchClass = launchClass;
}
public String getText() {
return mText;
}
public Class getLaunchClass() {
return mLaunchClass;
}
}
Next, we edit your fragment code to incorporate this change:
private static final String[] DUMMYTEXT = new String[]{
"Text One ",
"Text Two",
"Text Three",
"Text Four"
};
private static final Class[] LAUNCH_CLASSES = new Class[] {
FirstActivity.class,
SecondActivity.class,
ThirdActivity.class,
FourthActvity.class
....
};
When creating the items for your adapter:
mModels = new ArrayList<>();
for (int i = 0; i < DUMMYTEXT.length; i++) {
mModels.add(new Model(DUMMYTEXT[i], LAUNCH_CLASSES[i]));
}
Finally, your ViewHolder's
reaction to a click
event will change:
public ViewHolder(final View itemView) {
super(itemView);
context = itemView.getContext();
tvText = (TextView) itemView.findViewById(R.id.tvText);
}
public void bind(final Model model) {
tvText.setText(model.getText());
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = itemView.getContext();
Intent intent = new Intent(context,
model.getLaunchClass());
context.startActivity(intent);
}
});
}
Your model can now supply the relevant information.