RecyclerView + SearchView从搜索中打开活动

时间:2015-12-01 10:20:18

标签: android android-recyclerview searchview

我正在使用RecyclerView列出一些文本,SearchView用于搜索列表,当用户点击列表中的文本时,它会打开一个特定于该文本的新活动。在我使用SearchView之前,我刚收到了我的文本列表并使用了switch语句,如果用户点击第一行,它会打开第一个活动...

现在使用SearchView在底部搜索某些内容时,结果会弹出到列表的顶部,以便switch语句打开第一个错误的活动。

因此,当用户搜索时,我仍然坚持如何为列表中的正确文本打开正确的活动。有人可以帮我一个例子

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

2 个答案:

答案 0 :(得分:1)

这里的问题涉及数据绑定。您的model在选择(点击)的情况下不知道对它的期望。下面的例子可能看起来很复杂,但它的意思是强调这个问题。

让我们改变您的模型类:

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

接下来,我们编辑您的片段代码以包含此更改:

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

为适配器创建项目时:

mModels = new ArrayList<>();

for (int i = 0; i < DUMMYTEXT.length; i++) {
    mModels.add(new Model(DUMMYTEXT[i], LAUNCH_CLASSES[i]));
}

最后,您对ViewHolder's事件的click反应将发生变化:

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

您的模型现在可以提供相关信息。

答案 1 :(得分:0)

行为是正确的。因为当ListView重新对适配器进行更改时,它也会更改/刷新新列表项的位置。

但是根据你的逻辑位置,1会进入一个特定的活动。

我认为您必须强制执行模型中的位置,而不是使用getAdapterPosition()

获取位置 你可以做点什么,

mModels.get(getAdapterPosition()).getPosition();

假设getters and setters

int position Model class config/hooks.php