Это сложный вопрос, поэтому я прикрепил изображение, чтобы немного визуализировать. Как изменить цвета родительского фрагмента и представления RecyclerView в зависимости от позиции OnClickListener от recyclerview
Поэтому у меня есть recyclerview, который содержит палитру цветов. Он загружает цвета, создавая новый ImageView для каждого цвета, а затем изменяя цвет и извлекаемый из каждого изображения, имея другой для «выбранного цвета». Выбранный цвет также используется для изменения цвета панели инструментов из родительского диалогового окна.
Проблема заключается в том, что OnClicklistener не работал вообще после нескольких часов исследований. Прямо сейчас я не могу использовать OnClickListener без сбоя приложения.
Теперь давайте перейдем к действительному коду и проблемам. я объявлю (вам) некоторые переменные и классы, которые я использую:
ArrayList<String> colorsList = //arraylist which contains all the colors which can be displayed
NewNotebookFragment = //DialogFragment, contains a toolbar, miscellaneous views and a rvNewNotebook
RecyclerView rvNewNotebook = //the recyclerview containing imageviews representing each individual color retrieved from colorsList
NewNotebookAdapter = adapter which is bound to rvNewNotebook
Прямо сейчас, что я сделал это сделать метод в NewNotebookFragment называется changeColor, который может получить Int, представляющей позицию выбранного цвета. changeColor() изменяет цвет панели инструментов. changeColor() вызывается из метода onClick из OnclickListener, определенного в Viewholder в NewNotebookAdapter. Теперь идет фактический код.
newNotebookFragment:
public class NewNotebookFragment extends DialogFragment {
RecyclerView rvNewNotebook;
int activeColor;
ArrayList<String> colors=Helpers.getPossibleColors();
@Override
public View onCreateView ...}
@Override
public void onViewCreated(View v, Bundle savedInstanceState){
activeColor=new Random().nextInt(colors.size());
toolbar = (Toolbar) v.findViewById(R.id.newnotebooktoolbar);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return false;
}
});
toolbar.inflateMenu(R.menu.newnotebook);
toolbar.setTitle("Create new Notebook");
if(Helpers.isColorDark(Color.parseColor(colors.get(activeColor)))){
toolbar.setTitleTextColor(getResources().getColor(R.color.md_dark_primary_text));
}else{
toolbar.setTitleTextColor(getResources().getColor(R.color.md_light_primary_text));
}
rvNewNotebook = (RecyclerView) v.findViewById(R.id.rvNewNotebook);
final GridLayoutManager rvNotebookManager = new GridLayoutManager(getContext(),6);
rvNewNotebook.setLayoutManager(rvNotebookManager);
NewNotebookAdapter adapter= new NewNotebookAdapter(getContext(), Helpers.getPossibleColors(), activeColor);
toolbar.setBackgroundColor(Color.parseColor(Helpers.getPossibleColors().get(activeColor)));
rvNewNotebook.setAdapter(adapter);
Log.d("onViewCreated", ""+rvNewNotebook.getWidth());
}
@Override public void onResume(){...}
public static NewNotebookFragment newInstance() {...}
public void changeColor(int position){
if(Helpers.isColorDark(Color.parseColor(colors.get(position)))){
toolbar.setTitleTextColor(getResources().getColor(R.color.md_dark_primary_text));
}else{
toolbar.setTitleTextColor(getResources().getColor(R.color.md_light_primary_text));
}
toolbar.setBackgroundColor(Color.parseColor(Helpers.getPossibleColors().get(position)));
}
NewNotebookAdapter:
public class NewNotebookAdapter extends RecyclerView.Adapter<NewNotebookAdapter.ViewHolder>{
Context context;
ArrayList<String> colors = new ArrayList<>();
int activeColor;
public NewNotebookAdapter(){
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public ImageView ivSwatch;
public Toolbar toolbar;
public ViewHolder(View itemView) {
super(itemView);
ivSwatch = (ImageView) itemView.findViewById(R.id.ivSwatch);
toolbar = (Toolbar) itemView.findViewById(R.id.newnotebooktoolbar);
ivSwatch.setOnClickListener(this);
}
@Override
public void onClick(View view) {
NewNotebookFragment newNotebookFragment = new NewNotebookFragment();
final int adapterPosition = ViewHolder.this.getAdapterPosition();
Log.d("OnClick. Adapter", "getAdapterPosition: "+adapterPosition);
newNotebookFragment.changeColor(adapterPosition);
}
}
public NewNotebookAdapter(Context context, ArrayList<String> colors, int activeColor){
this.context=context;
this.colors=colors;
this.activeColor=activeColor;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.colorcircle,parent,false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Drawable drawablefull = ContextCompat.getDrawable(context,R.drawable.colorcircle);
Drawable drawableHollow = ContextCompat.getDrawable(context,R.drawable.coloroutlinecircle);
if (position==activeColor){
holder.ivSwatch.setImageDrawable(drawablefull.mutate());
}else if (position!=activeColor){
holder.ivSwatch.setImageDrawable(drawableHollow.mutate());
}
holder.ivSwatch.setColorFilter(Color.parseColor(colors.get(position)));
Текущая проблема у меня есть следующие трассировки стека:
FATAL EXCEPTION: main
Process: com.twotowerstudios.virtualnotebookdesign, PID: 32272
java.lang.IllegalStateException: Fragment NewNotebookFragment{b10003e} not attached to Activity
at android.support.v4.app.Fragment.getResources(Fragment.java:648)
at com.twotowerstudios.virtualnotebookdesign.NewNotebookDialog.NewNotebookFragment.changeColor(NewNotebookFragment.java:85)
at com.twotowerstudios.virtualnotebookdesign.NewNotebookDialog.NewNotebookAdapter$ViewHolder.onClick(NewNotebookAdapter.java:49)
at android.view.View.performClick(View.java)
at android.view.View$PerformClick.run(View.java)
at android.os.Handler.handleCallback(Handler.java)
at android.os.Handler.dispatchMessage(Handler.java)
at android.os.Looper.loop(Looper.java)
at android.app.ActivityThread.main(ActivityThread.java)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
Теперь я почти уверен, что это связано с мой метод onClick, который создает новый экземпляр NewNotebookFragment, вызывая fr agment Я использую метод onClick, фактически не тот, который уже используется и отображается. ОДНАКО, я делаю эту тему, потому что у меня нет реальной идеи о том, как решить проблему в целом. Я не знаю, как я мог бы, например, получить фактический NewNotebookFragment из метода onClick, чтобы я мог его изменить или вызвать из него методы. Я не знаю, исправлено ли когда-то s, если оно будет работать или что-то еще. Как я могу заставить это работать?
Редактировать: Я отлично работал. В основном то, что я сделал, это определить setonclickListener внутри onBindViewHolder, в Imageviews. Функция clickListener вызовет интерфейс под названием AdapterInterface и использует в нем метод clickListener, который позволяет мне передать int цвета родительскому фрагменту. Фрагмент реализует этот интерфейс, определенный в адаптере, и он будет переопределять clickListener, используя переданный ему цвет, и из него вызывает метод changeColor. Если кто-нибудь в будущем нуждается в примерах, не стесняйтесь обращаться ко мне. Соответствующие изменения находятся в этих двух файлах, загруженных в Github: https://gist.github.com/coldblade2000/0c2cac8b1af4df5985fe6cebebc9cff2. Ссылки содержат определенный уровень объяснения и документации по двум классам.
Я не в моем компьютере, но я думаю, что вы только что привел меня на правильном пути с интерфейсами. В то время я узнал, что это такое. Как только я закончу, я отправлю свой фиксированный код. Хотя я не очень хорошо понял. Как я могу изменить детей recycliewiew? Могу ли я уничтожить и воссоздать recyclerview с другим activeColor из моего фрагмента? – coldblade2000
Вы можете удалить/изменить дочерний индекс из ArrayList, который прикреплен, в вашем случае, цвета и использовать notifyItemRemoved() или notifyItemChanged() для просмотра ресайклера для обновления. Или, если изменился весь массив данных массива, используйте notifyDataSetChanged() –