Как из адаптера открыть новую активити?
Получается код имеет следующий вид:
@Override
public void onBindViewHolder(DataAdapter.ViewHolder holder, int position) {
final Phone phone = phones.get(position);
holder.imageView.setImageResource(phone.getImage());
holder.nameView.setText(phone.getName());
holder.companyView.setText(phone.getCompany());
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("кликнул по: ", phone.getClickbutton());
startActivity(new Intent(this, Information.class));
}
});
}
Соответственно
startActivity(new Intent(this, Information.class));
Не хочет тут работать.
Привожу полный код адаптера:
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private LayoutInflater inflater;
private List<Phone> phones;
public DataAdapter(Context context, List<Phone> phones) {
this.phones = phones;
this.inflater = LayoutInflater.from(context);
}
@Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.list_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(DataAdapter.ViewHolder holder, int position) {
final Phone phone = phones.get(position);
holder.imageView.setImageResource(phone.getImage());
holder.nameView.setText(phone.getName());
holder.companyView.setText(phone.getCompany());
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("кликнул по: ", phone.getClickbutton());
startActivity(new Intent(this, Information.class));
}
});
}
@Override
public int getItemCount() {
return phones.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
final ImageView imageView;
final TextView nameView, companyView;
final Button button;
ViewHolder(View view){
super(view);
imageView = (ImageView)view.findViewById(R.id.image);
nameView = (TextView) view.findViewById(R.id.name);
companyView = (TextView) view.findViewById(R.id.company);
button = (Button) view.findViewById(R.id.button);
}
}
}
Вот собственно вопрос. Как мне открыть из адаптера новую активити... Спасибо.
Ответы (2 шт):
Начнем с того, что ваш адаптер и не должен уметь ее открывать. Адаптер должен уметь только показывать список ваших элементов. А клики обрабатывает View в которой находится адаптер.
Как это правильно сделать? Создайте свой интерфейс, что-то вроде такого:
interface ItemClickListener{
onItemClick(data: YourData);
}
Реализуйте его в вашей View (Activity, Fragment или любая другая View). Сам интерфейс можно передать либо в конструктор адаптера, либо методом. Собстевнно при клике на ваш элемент вызывайте клик у вашего листенера. Тогда проблем с вызовом активити не будет и вы разделите ответственность.
Вот тут есть хорошая статья на эту тему.
UPD: Пример адаптера:
class YourAdapter extends RecyclerView.Adapter<YourAdapter.ViewHolder> {
private final ItemClickListener listener;
private final List<YourData> items = new ArrayList<>();
public YourAdapter(ItemClickListener listener) {
this.listener = listener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View root = LayoutInflater.from(parent.getContext()).inflate(viewType, null, false);
return new ViewHolder(root);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.bind(items.get(position), listener);
}
@Override
public int getItemCount() {
return items.size();
}
public void update(List<YourData> items){
this.items.clear();
this.items.addAll(items);
notifyDataSetChanged();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private Button buttonOne;
private Button buttonTwo;
ViewHolder(View itemView) {
super(itemView);
buttonOne = itemView.findViewById(R.id.button_one);
buttonTwo = itemView.findViewById(R.id.button_two);
}
void bind(YourData data, ItemClickListener listener){
buttonOne.setOnClickListener(v -> listener.onClickButtonOne(data));
buttonTwo.setOnClickListener(v -> listener.onClickButtonTwo(data));
}
}
}
В активити:
class MainActivity extends AppCompatActivity implementes ItemClickListener {
//some code
@Override
public void onItemClick(data: YourData){
Intent intent = ...// Тут положите ваши данные в бандл, а бандл в интент
startActivity(intent);
}
}
Проблему помогли решить тут - https://stackoverflow.com/questions/62209329/how-to-open-a-new-activity-from-the-adapter Всё оказалось как я и думал очень просто.
Добавил context:
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private LayoutInflater inflater;
private List<Phone> phones;
private Context context;
public DataAdapter(Context context, List<Phone> phones) {
this.context = context;
this.phones = phones;
this.inflater = LayoutInflater.from(context);
}
// Remainder code
}
И изменил функцию:
@Override
public void onBindViewHolder(DataAdapter.ViewHolder holder, int position) {
final Phone phone = phones.get(position);
holder.imageView.setImageResource(phone.getImage());
holder.nameView.setText(phone.getName());
holder.companyView.setText(phone.getCompany());
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("click: ", phone.getClickbutton());
context.startActivity(new Intent(context, Information.class));
}
});
}
Профит!