RecyclerView массива кнопок - как обновить данные? - PullRequest
2 голосов
/ 10 июля 2020

Это мой первый вопрос на сайте, постараюсь хорошо его сформировать. У меня есть recyclerView, а элемент - это массив кнопок. При нажатии кнопки отображается всплывающее меню, которое позволяет пользователю изменить цвет кнопки. Мне удалось установить, что метод onClick изменит цвет, но я не знаю, как сохранить выбранный цвет в ButtonArrayList, который содержит цвета.

Проблема в том, что когда кнопка нажата, не знаю, как программно понять, на какой кнопке, в каком массиве кнопок она была нажата.

Спасибо!

Просто чтобы продемонстрировать проблему. когда кнопка нажата, как определить, какая кнопка из какого элемента была нажата? 1

Код фрагмента:

package com.examples.recyclerViewWithButtonArray;

import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.util.LinkedList;


/**
 * A simple {@link Fragment} subclass.
 * Use the {@link Game#newInstance} factory method to
 * create an instance of this fragment.
 */
public class Game extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    protected static int[] mButtonsColors;

    private final LinkedList<ButtonArray> mButtonArrayList = new LinkedList<>();
    RecyclerView mGuessLinesRecyclerView;
    ButtonArrayListAdapter mButtonArrayListAdapter;
    FloatingActionButton mFab;

    // TODO: Rename and change types of parameters

    public Game() {
        // Required empty public constructor
    }

    public static Game newInstance(String param1, String param2) {
        Game fragment = new Game();
        return fragment;
    }

    private void initGameColors(){
        mButtonsColors = new int[4];
        int[] c = getContext().getResources().getIntArray(R.array.buttonColors);
        //asign colors
        for (int i = 0; i < 4; i++) {
            this.mButtonsColors[i] = c[i];
            }
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initGameColors();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View vw = inflater.inflate(R.layout.fragment_game, container, false);
        return vw;
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mGuessLinesRecyclerView = view.findViewById(R.id.recycler_view);
        mFab = view.findViewById(R.id.fab);
        //initialize recyclerView
        // Create an adapter and supply the data to be displayed.
        mButtonArrayListAdapter = new ButtonArrayListAdapter(getContext(), mButtonArrayList, this);
        // Connect the adapter with the RecyclerView.
        mGuessLinesRecyclerView.setAdapter(mButtonArrayListAdapter);
        // Give the RecyclerView a default layout manager.
        mGuessLinesRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

        //initializeFAB
        mFab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mButtonArrayList.add(new ButtonArray(getContext(),mButtonsColors));
                mGuessLinesRecyclerView.setAdapter(mButtonArrayListAdapter);
            }
        });


        //add first array to the recycler view.
        // Next guess lines will be added when clicking on movableFab
        mButtonArrayList.add(new ButtonArray(getContext(), this.mButtonsColors));
    }
}



Код ButtonArrayListAdapter:

package com.examples.recyclerViewWithButtonArray;

import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public class ButtonArrayListAdapter extends RecyclerView.Adapter<ButtonArrayListAdapter.ButtonArrayViewHolder> {
    private final Context mContext;
    private final List<ButtonArray> mData;
    class ButtonArrayViewHolder extends RecyclerView.ViewHolder {
        public ArrayList<Button> mButtons;
        final ButtonArrayListAdapter mAdapter;
        public ButtonArrayViewHolder(@NonNull View itemView, ButtonArrayListAdapter adapter) {
            super(itemView);
            this.mAdapter = adapter;
            mButtons =new ArrayList<>();
            if(4==4)
            {
                //create an array of button for binding
                mButtons.add((Button)itemView.findViewById(R.id.button_Guess1));
                mButtons.add((Button)itemView.findViewById(R.id.button_Guess2));
                mButtons.add((Button)itemView.findViewById(R.id.button_Guess3));
                mButtons.add((Button)itemView.findViewById(R.id.button_Guess4));
            }
        }
    }

    public ButtonArrayListAdapter(Context mContext, List<ButtonArray> mData, Game mGame) {
        this.mContext = mContext;
        this.mData = mData;
    }

    @NonNull
    @Override
    public ButtonArrayViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View layout;
        layout = LayoutInflater.from(mContext).inflate(R.layout.guess_line,parent,false);
        return new ButtonArrayViewHolder(layout,this);
    }

    @Override
    public void onBindViewHolder(@NonNull final ButtonArrayViewHolder buttonArrayViewHolder, final int position) {
        //bind data here
        //initiate each guessLineButton
        for (int i = 0; i < 4; i++) {
            int c = mData.get(position).mAnswerButtonsColors[i];
            final Button bt = buttonArrayViewHolder.mButtons.get(i);
            //set initial button color
            bt.setBackgroundColor(c);
            //set button clik to open color chooser
            bt.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int[] chooseColorButtons = new int[4];

                    // inflate the layout of the popup window
                    final View popupView = LayoutInflater.from(mContext).inflate(R.layout.choose_color_popup,null);
                    // create the popup window
                    int width = bt.getWidth();
                    int height = LinearLayout.LayoutParams.WRAP_CONTENT;
                    boolean focusable = true; // lets taps outside the popup also dismiss it
                    final PopupWindow popupWindow = new PopupWindow(popupView, width, height, focusable);

                    // show the popup window
                    // which view you pass in doesn't matter, it is only used for the window tolken
                    int[] loc = new int[]{0,0};
                    bt.getLocationOnScreen(loc);
                    popupWindow.showAtLocation(v, Gravity.TOP|Gravity.LEFT, loc[0], loc[1] + bt.getHeight());
                    // dismiss the popup window when touched
                    popupView.setOnTouchListener(new View.OnTouchListener() {
                        @Override
                        public boolean onTouch(View v, MotionEvent event) {
                            popupWindow.dismiss();
                            return true;
                        }
                    });

                    //initiate each color choose button
                    if(chooseColorButtons.length==4) {
                        chooseColorButtons[0] = R.id.buttonColor1;
                        chooseColorButtons[1] = R.id.buttonColor2;
                        chooseColorButtons[2] = R.id.buttonColor3;
                        chooseColorButtons[3] = R.id.buttonColor4;
                    }

                    for (int j = 0; j < 4 ; j++) {
                        Button colbt = (Button)(popupView.findViewById(chooseColorButtons[j]));
                        colbt.setBackgroundColor(Game.mButtonsColors[j]);

                        colbt.setTextColor(Game.mButtonsColors[j]);
                        colbt.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                bt.setBackgroundColor(((ColorDrawable)(((Button)v).getBackground())).getColor());
//WHAT SHOULD I DO HERE?
                                popupWindow.dismiss();
                            }
                        });
                    }

                }
            });

        }

    }

    @Override
    public int getItemCount() {
        return mData.size();
    }
}

1 Ответ

2 голосов
/ 12 июля 2020

После прочтения вашего вопроса я получаю следующее: вы хотите сохранить цвет для каждой кнопки, поэтому в следующий раз, когда эта кнопка щелкнет, должен загрузиться тот же цвет, если да, тогда вы можете рассмотреть эти предложения tw0

1- if количество кнопок равно c, и вы не добавляете их динамически, тогда вы можете жестко запрограммировать цвет для каждой кнопки, добавив их в список и назначив их вручную для каждой кнопки.

2- вы можете использовать пара ключ-значение (ha sh map), это лучшее решение для любого случая, когда вы добавляете кнопку вручную или динамически, просто сохраняете цвет для каждого ключа. В этом случае кнопки должны быть вашими клавишами, а цвета будут иметь значение.

Спасибо

...