Recycler View Onclick метод в деятельности?
Я пытаюсь создать интерфейс, похожий на Google Keep. Я знаю, как создать вид в шахматном порядке, используя вид Recycler. Если я нажму на конкретную карту. Тогда это должно открыть деятельность.
Я могу добиться этого с помощью метода onclick.
Этот же сценарий происходит по крайней мере в 5 различных видах деятельности в моем приложении.
Мой вопрос в том, что
Могу ли я использовать этот единственный адаптер во всех этих 5 местах?
Если да, где я должен разместить действия onclick?
Если нет, как я могу создать разнесенный макет, такой как Keep?
Заранее спасибо!
1 ответ
(См. Приложение для RecyclerView ниже в изменениях)
Как я уже упоминал в своем комментарии, безусловно, хорошо иметь отдельные адаптеры для всех ваших действий, которые используют разные данные и представления. По мере того, как данные и макеты вашего приложения становятся все более сложными, ваш код... так оно и есть.
Но если некоторые из ваших Деятельностей использовали аналогичные данные в своих ListViews - может быть, например, два TextViews и ImageButton - вы могли бы сэкономить некоторые усилия, определив один адаптер, который можно использовать для нескольких Деятельностей. Затем вы будете создавать отдельные объекты для каждого действия, подобно тому, как вы создаете несколько ArrayAdapter<String>
объекты для заполнения нескольких ListViews.
BaseAdapter
отличный класс для расширения при написании специального адаптера. Он гибкий и позволяет вам полностью контролировать данные, которые отображаются в вашем ListView. Вот минимальный пример:
public class CustomBaseAdapter extends BaseAdapter {
private Context context;
private ArrayList<String> listData;
public CustomBaseAdapter(Context context, ArrayList<String> listData) {
this.context = context;
this.listData = listData;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.your_list_item_layout, parent, false);
//populate the view with your data -- some examples...
TextView textData = (TextView) convertView.findViewById(R.id.yourTextView);
textData.setText(listData.get(position));
ImageButton button = (ImageButton) convertView.findViewById(R.id.yourImageButton);
button.setOnClickListener(new View.OnClickListener() {
//...
//...
});
}
return convertView;
}
@Override
public Object getItem(int position) {
return 0;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public int getCount() {
return listData.size();
}
}
Таким образом, ключевая часть этого кода, очевидно, getView()
метод, который вызывается каждый раз, когда ListView нужны данные для отображения. Для эффективности представления хранятся в чем-то, что называется convertView
поэтому их можно использовать повторно, и их не нужно раздувать каждый раз, когда на экране появляется вид.
Итак, что мы делаем в getView()
сначала выяснить, если convertView
существует. Если это произойдет, мы просто передадим это обратно вызывающему ListView, потому что все уже должно быть создано и готово к работе. Если convertView
имеет значение null, это означает, что данные не были созданы (или должны быть созданы по какой-либо причине), поэтому мы раздуваем совершенно новый взгляд и заполняем его нашими данными.
Таким образом, в случае с приведенным выше примером адаптера, если все ваши действия отображают один список строк, вы можете повторно использовать этот адаптер для каждого, передавая разные ArrayList<String>
через конструктор каждый раз, когда вы создали новый объект. Но очевидно, что вы могли бы передать больше, чем просто строки, если бы у вас было больше данных для отображения. Уровень сложности зависит от вас. И если бы разница между вашими действиями была слишком велика, я бы просто создал пользовательские версии этого класса для всех них и просто создал бы их экземпляры и заполнил их так, как вам нравится. Это сохранит все ваши данные очень организованными и инкапсулированными.
Надеюсь это поможет! Не стесняйтесь задавать вопросы для получения дополнительных разъяснений, если вам это нужно.
РЕДАКТИРОВАТЬ В ОТВЕТ НА КОММЕНТАРИИ
Поскольку вы используете RecyclerView вместо просто ListViews (который я по какой-то причине совершенно забыл), вы все равно можете сделать что-то очень похожее, используя RecyclerView.Adapter<YourViewHolder>
вместо. Разница была бы в том, что вместо того, чтобы раздувать взгляды в getView()
метод, они надуваются внутри вашего обычая ViewHolder
, который я полагаю, у вас уже есть. Код может выглядеть примерно так:
public class CustomRecyclerViewAdapter extends RecyclerView.Adapter<StringViewHolder> {
private final List<String> items;
public CustomRecyclerViewAdapter(ArrayList<String> items) {
this.items = items;
}
@Override
public StringViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//So instead of inflating the views here or in a getView() like in
//in the BaseAdapter, you would instead inflate them in your custom
//ViewHolder.
return new StringViewHolder(parent);
}
@Override
public void onBindViewHolder(StringViewHolder holder, int position) {
holder.setModel(items.get(position));
}
@Override
public long getItemId(int position) {
return items.get(position).hashCode();
}
@Override
public int getItemCount() {
return items.size();
}
}