Разрабатывается приложение, в котором используются фрагменты. Пытаюсь реализовать смену фрагмента по нажатию на любой item в recyclerView. Обработка нажатия происходит в адаптере.
TimeReportAdapter.java
public class TimeReportAdapter extends RecyclerView.Adapter<ViewHolder> {
public OnTimeReportAdapterActionListener mTimeReportAdapterCallBack;
public interface OnTimeReportAdapterActionListener {
void onMinuteReportAction();
}
private Context context;
private List<TimeReport> mReportList = Collections.emptyList();
private SharedPreferences mSettings;
private static final String APP_PREFERENCES = "myValues";
private static final String APP_PREFERENCES_DATE = "date";
private Intent mIntent;
public TimeReportAdapter(Context context, List<TimeReport> reportList) {
this.context = context;
this.mReportList = reportList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_time_report, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final TimeReport report = mReportList.get(position);
holder.tv_time.setText(report.getmTime());
holder.tv_count.setText(String.valueOf(report.getmCount()));
// обработка нажатия по item
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// запись в SharedPreferences
mSettings = context.getApplicationContext().getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = mSettings.edit();
editor.putString(APP_PREFERENCES_DATE, report.getmTime());
editor.apply();
Log.d("savedSharedPreferences", APP_PREFERENCES_DATE +" "+ report.getmTime());
// вызов смены фрагмента
mTimeReportAdapterCallBack.onMinuteReportAction();
}
});
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mTimeReportAdapterCallBack = (OnTimeReportAdapterActionListener) activity;
} catch (ClassCastException e) {
FirebaseCrash.report(e);
throw new ClassCastException(activity.toString()
+ " must implement OnTimeReportAdapterActionListener");
}
}
@Override
public int getItemCount() {
return mReportList.size();
}}
TimeReportFragment.java
public class TimeReportFragment extends Fragment {
private static View mRootView = null;
private ImageButton mRefreshBtn = null; // кнопка "обновить"
private ArrayList<TimeReport> mTimeReports = null;
private TimeReportAdapter mTimeReportAdapter = null;
private RecyclerView mRecycler = null;
private ProgressBar mProgressBar = null; // анимация загрузки
private LinearLayout mHeader = null;
private View mLine = null;
public Adapter adapter;
public TimeReportFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_time_report, container, false);
initializeViews();
doSendTimeReportRequest(); // отправка запроса, получение, парсинг json, установка в recyclerView
mRefreshBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
doSendTimeReportRequest();
}
});
return mRootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mTimeReportAdapter.setInterface((TimeReportAdapter.OnTimeReportAdapterActionListener) activity);
//mTimeReportFragmentCallBack = (TimeReportFragment.OnTimeReportFragmentActionListener) activity;
} catch (ClassCastException e) {
FirebaseCrash.report(e);
throw new ClassCastException(activity.toString()
+ " must implement OnTimeReportFragmentActionListener");
}
}
TimeReportAdapter.java (обновленный)
public class TimeReportAdapter extends RecyclerView.Adapter<ViewHolder> {
public OnTimeReportAdapterActionListener mTimeReportAdapterCallBack;
public interface OnTimeReportAdapterActionListener {
void onMinuteReportAction();
}
private Fragment fragment;
private MainActivity mainActivity;
private Context context;
private List<TimeReport> mReportList = Collections.emptyList();
private SharedPreferences mSettings;
private static final String APP_PREFERENCES = "myValues";
private static final String APP_PREFERENCES_DATE = "date";
public TimeReportAdapter(Context context, List<TimeReport> reportList) {
this.context = context;
this.mReportList = reportList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_time_report, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final TimeReport report = mReportList.get(position);
holder.tv_time.setText(report.getmTime());
holder.tv_count.setText(String.valueOf(report.getmCount()));
// обработка нажатия по item
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// запись в SharedPreferences
mSettings = context.getApplicationContext().getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = mSettings.edit();
editor.putString(APP_PREFERENCES_DATE, report.getmTime());
editor.apply();
Log.d("savedSharedPreferences", APP_PREFERENCES_DATE +" "+ report.getmTime());
// вызов смены фрагмента
mTimeReportAdapterCallBack.onMinuteReportAction();
//mTimeReportAdapterCallBack.onMinuteReportAction();
}
});
}
public void setInterface(OnTimeReportAdapterActionListener myInterface) {
this.mTimeReportAdapterCallBack = myInterface;
}
@Override
public int getItemCount() {
return mReportList.size();
}}
Конструкция приложения такова, что смена всех фрагментов происходит в MainActivity с которым взаимодействуют фрагменты через интерфейсы. Приложение разрабатываю не с нуля, поэтому структуру менять не могу.
Чтобы все заработало необходимо реализовать метод onAttach(). Но для этого нужно наследоваться от Fragment, а не RecyclerView.Adapter. Как быть?
Вопрос: как реализовать метод onAttach(), или как по другому реализовать вызов mTimeReportAdapterCallBack.onMinuteReportAction() чтобы он не был null?
В адаптере есть следующий метод, переопределите его и получите context из recyclerview, context и есть ваше activity которое можно преобразовать в интерфейс
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
context = recyclerView.getContext();
}
onAttach - это метод фрагмента. Реализовать его в адаптере невозможно.
Вам надо действовать иначе. Судя по приведённому коду, вам лучше всего сделать сеттер для вашего интерфейса и передавать его экземпляр из фрагмента в адаптер при вызове onAttach у фрагмента.
Примерно так:
public class Fr extends Fragment {
Adapter adapter;
public void onAttach(Activity activity) {
super.onAttach(activity);
adapter.setInterface((OnTimeReportAdapterActionListener) activity);
}
public void onDetach() {
super.onDetach();
adapter.setInterface(null);
}
}
public class Adapter extends RecyclerView.Adapter {
public void setInterface(Interface myInterface) {
this.myInterface = myInterface;
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
В java все объект могут быть mutable и immutableПонятно, что, например, строка является immutable
Здравствуйте! Второй день пытаюсь пофиксить проблемуВ проекте пытаюсь достать данные из базы, но вылетает NullPointerException
Всем доброго дня! Сервер написан на Java + Spring framework + PostgresqlМне нужно выдавать JSON такого вида:
Как определить штат по координатам, без запросов к google mapЖелательно оффлайн