如何根据来自 recyclerview 的 OnClickListener 位置更改父片段的颜色和 RecyclerView 的视图
How to change colors of parent Fragment and views of RecyclerView depending on OnClickListener position from recyclerview
这是一个困难的问题,所以我附上了一张图片来帮助形象化一点。
所以我有一个包含调色板的 recyclerview。它通过为每种颜色创建一个新的 ImageView 来加载颜色,然后更改每个图像视图的颜色和可绘制对象,"selected color" 具有不同的颜色。所选颜色还用于从父 DialogFragment 更改工具栏的颜色。
问题来了,经过数小时的研究,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() 是从 OnclickListener 的 onClick 方法调用的,在 NewNotebookAdapter 的 Viewholder 中定义。
现在是实际代码。
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)));
}
新笔记本适配器:
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 实例,导致我在 onClick 方法中使用的片段实际上与已经存在的片段不同被使用和展示。但是,我正在创建此线程,因为我对如何从整体上解决问题没有真正的想法。例如,我不知道如何从 onClick 方法中获取实际的 NewNotebookFragment,以便修改它或从中调用方法。我不知道是否曾经
如果它甚至可以工作或任何东西,它是固定的。我怎样才能让它工作?
编辑:我让它运行得很好。基本上我所做的是在 Imageviews 的 onBindViewHolder 中定义 setonclickListener。 clickListener 将调用一个名为 AdapterInterface 的接口,并在其中使用一个名为 clickListener 的方法,该方法允许我将颜色的 int 传递给父片段。该片段将实现适配器中定义的接口,并且它将覆盖 clickListener,使用传递给它的颜色并从中调用 changeColor 方法。如果以后有人需要示例,请随时与我联系。相关更改在这两个文件中,已上传到 Github:https://gist.github.com/coldblade2000/0c2cac8b1af4df5985fe6cebebc9cff2 链接包含有关这两个 类
的一定程度的解释和文档
查看您的代码,每次单击它时都会创建一个新片段。我相信您想要的是更改对话框片段工具栏的颜色。您可以做的第一件事是创建一个接口侦听器作为 Fragment 的回调,它被传递到 Adapter 中。像这样
public interface ViewHolderOnClickListener {
//This method can be any parameters, I'm pasing color here since you need the color code
public void onViewHolderClick(View itemView, int position, int color);
}
然后在您的适配器和视图持有者构造函数方法中,添加一个接口实例作为您的参数。您可以直接在创建 Adapter 时传递它,也可以让您的 Fragment 实现接口并使用 "this"
传递它
public TempAdapter(ViewHolderOnClickListener viewHolderOnClickListener) {
this.viewHolderOnClickListener = viewHolderOnClickListener;
}
然后在您的 ViewHolder 中,使用
进行回调
@Override
public void onClick(View view) {
viewHolderOnClickListener.onViewHolderClick(*PARAMS HERE*);
}
这样,您的片段就可以监听 ViewHolder 内部发生的 OnClick 事件,并做出相应的响应。
另一种方法是使用EventBuses
这是一个困难的问题,所以我附上了一张图片来帮助形象化一点。
所以我有一个包含调色板的 recyclerview。它通过为每种颜色创建一个新的 ImageView 来加载颜色,然后更改每个图像视图的颜色和可绘制对象,"selected color" 具有不同的颜色。所选颜色还用于从父 DialogFragment 更改工具栏的颜色。
问题来了,经过数小时的研究,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() 是从 OnclickListener 的 onClick 方法调用的,在 NewNotebookAdapter 的 Viewholder 中定义。 现在是实际代码。
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)));
}
新笔记本适配器:
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 实例,导致我在 onClick 方法中使用的片段实际上与已经存在的片段不同被使用和展示。但是,我正在创建此线程,因为我对如何从整体上解决问题没有真正的想法。例如,我不知道如何从 onClick 方法中获取实际的 NewNotebookFragment,以便修改它或从中调用方法。我不知道是否曾经 如果它甚至可以工作或任何东西,它是固定的。我怎样才能让它工作?
编辑:我让它运行得很好。基本上我所做的是在 Imageviews 的 onBindViewHolder 中定义 setonclickListener。 clickListener 将调用一个名为 AdapterInterface 的接口,并在其中使用一个名为 clickListener 的方法,该方法允许我将颜色的 int 传递给父片段。该片段将实现适配器中定义的接口,并且它将覆盖 clickListener,使用传递给它的颜色并从中调用 changeColor 方法。如果以后有人需要示例,请随时与我联系。相关更改在这两个文件中,已上传到 Github:https://gist.github.com/coldblade2000/0c2cac8b1af4df5985fe6cebebc9cff2 链接包含有关这两个 类
的一定程度的解释和文档查看您的代码,每次单击它时都会创建一个新片段。我相信您想要的是更改对话框片段工具栏的颜色。您可以做的第一件事是创建一个接口侦听器作为 Fragment 的回调,它被传递到 Adapter 中。像这样
public interface ViewHolderOnClickListener {
//This method can be any parameters, I'm pasing color here since you need the color code
public void onViewHolderClick(View itemView, int position, int color);
}
然后在您的适配器和视图持有者构造函数方法中,添加一个接口实例作为您的参数。您可以直接在创建 Adapter 时传递它,也可以让您的 Fragment 实现接口并使用 "this"
传递它 public TempAdapter(ViewHolderOnClickListener viewHolderOnClickListener) {
this.viewHolderOnClickListener = viewHolderOnClickListener;
}
然后在您的 ViewHolder 中,使用
进行回调@Override
public void onClick(View view) {
viewHolderOnClickListener.onViewHolderClick(*PARAMS HERE*);
}
这样,您的片段就可以监听 ViewHolder 内部发生的 OnClick 事件,并做出相应的响应。
另一种方法是使用EventBuses