Как изменить цвет фона каждого элемента в ListView? - PullRequest
1 голос
/ 23 мая 2019

Я занимаюсь разработкой приложения с интерфейсом текстовых сообщений (что-то вроде Facebook Messenger, Whatsapp и т. Д.).Я хочу иметь возможность изменять цвет фона всех пузырей чата (ListView из TextView с), отправляемых пользователем, когда они выбирают новый цвет (в NavigationView).

Однако, с моим текущим кодом, я могу изменить цвет только после того, как EditText, использованный для составления сообщения, будет снова нажат.Или я могу редактировать только первый отправленный пузырь, но как только цвет меняется.

Вот что я попробовал:

ItemColor1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v){

        Toast.makeText(activity, "Couleur mise à jour", Toast.LENGTH_SHORT).show();
        currentTheme = position;
        SharedPreferences.Editor editor = pref.edit();
        editor.putInt("indexColorSelected",currentTheme);
        editor.apply();
        chatAdapter.notifyDataSetChanged();
        //the following changes only the first message sent     
        for(int i=0; i<chatAdapter.getCount(); i++){
            ChatData message = chatMessageList.get(position);
            TextView msg = activity.findViewById(R.id.text);
            msg.setText(message.body);
            msg.setBackgroundResource(R.drawable.user_color1);
        }
    }
});

ChatData - это пользовательский класс, который ясоздан, который выглядит следующим образом:

public class ChatAdapter extends BaseAdapter {

    private static LayoutInflater inflater = null;
    private ArrayList<ChatData> chatMessageList;
    private Context mContext;

    ChatAdapter(Activity activity, ArrayList<ChatData> list) {
        mContext = activity;
        chatMessageList = list;
        inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    ...
}

Цветная прорисовка:

    <corners
        android:bottomRightRadius="5dp"
        android:radius="40dp"/>

    <gradient
        android:angle="45"
        android:endColor="#01f1fa"
        android:startColor="#0189ff"
        android:type="linear" />

</shape>

getView() метод Адаптера:

public View getView(int position, View convertView, ViewGroup parent) {
    ChatData message = chatMessageList.get(position);
    View vi = convertView;

    if (convertView == null)
        vi = inflater.inflate(R.layout.msglist, parent, false);

    TextView msg = vi.findViewById(R.id.text);
    msg.setText(message.body);

    LinearLayout layout = vi.findViewById(R.id.message_layout);
    LinearLayout parent_layout = vi.findViewById(R.id.message_layout_parent);

    inflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    // if message is mine then align to right
    if (message.isMine) {
        layout.setGravity(Gravity.RIGHT);

        int couleurBubble = getCouleurSelectionnee();

        switch(couleurBubble){
            case R.color.c1: msg.setBackgroundResource(R.drawable.user_color1); break;
            case R.color.c2: msg.setBackgroundResource(R.drawable.user_color2); break;
            case R.color.c3: msg.setBackgroundResource(R.drawable.user_color3); break;
            case R.color.c4: msg.setBackgroundResource(R.drawable.user_color4); break;
            case R.color.c5: msg.setBackgroundResource(R.drawable.user_color5); break;
            case R.color.c6: msg.setBackgroundResource(R.drawable.user_color6); break;
            case R.color.c7: msg.setBackgroundResource(R.drawable.user_color7); break;
            case R.color.c8: msg.setBackgroundResource(R.drawable.user_color8); break;
            default: break;
        }

        parent_layout.setGravity(Gravity.RIGHT);
    }
    // If not mine then align to left
    else {
        layout.setGravity(Gravity.LEFT);
        msg.setBackgroundResource(R.drawable.bot_chat);
        parent_layout.setGravity(Gravity.LEFT);
    }
    return vi;
}

Я действительно не знаюкуда идти отсюда, так что любая помощь будет оценена.Если вы хотите, чтобы я предоставил больше кода, дайте мне знать, и я сообщу.

Спасибо.

1 Ответ

1 голос
/ 23 мая 2019

Я поделюсь, как бы я это сделал.Может быть, это может помочь вам.Есть какая-то странная проблема, потому что вы звоните notifyDataSetChanged().Этого будет достаточно, чтобы перерисовать все пузырьки сообщений.

Моя идея:

Добавить переменную int в класс адаптера (mColorResource).Эта переменная будет указывать на правильный чертеж, который следует использовать (например, R.drawable.user_color1).

public class ChatAdapter extends BaseAdapter {

    int mColorResource;

    ChatAdapter(Activity activity, ArrayList<ChatData> list, int initialColorResource) {
        mContext = activity;
        chatMessageList = list;
        inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        // You must receive the color on the construtor
        mColorResource = initialColor;
    }

    // Use this method to update the color (when user select a new color)
    public void setColor(int newColorResource) {
        mColorResource = newColorResource;
    }


    public View getView(int position, View convertView, ViewGroup parent) {
        ...
        // Note how this if-else is cleaner now
        if (message.isMine) {
            layout.setGravity(Gravity.RIGHT);
            msg.setBackgroundResource(mColorResource);
            parent_layout.setGravity(Gravity.RIGHT);
        } else {
            layout.setGravity(Gravity.LEFT);
            msg.setBackgroundResource(R.drawable.bot_chat);
            parent_layout.setGravity(Gravity.LEFT);
        }
        ...
    }
}

Затем, когда выбран цвет, найдите правильный чертеж на основе выбранного щелчка и передайте егоадаптер:

ItemColor1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v){
        Toast.makeText(activity, "Couleur mise à jour", Toast.LENGTH_SHORT).show();
        currentTheme = position;

        SharedPreferences.Editor editor = pref.edit();
        editor.putInt("indexColorSelected", currentTheme);
        editor.apply();

        // Here, you send the proper drawable...
        // I'm not sure how you convert color selected to the drawable
        // So, add your logic to convert the button clicked to a drawable here
        // like R.drawable.user_color1
        chatAdapter.setColor(R.drawable.NAME_OF_THE_COLOR);

        // Request to re-draw all items from the list (all bubbles)
        chatAdapter.notifyDataSetChanged();
    }
});

Кроме того, в своей деятельности вы создаете адаптер с последним использованным цветом.Что-то вроде:

@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ....
    // Set a default color (if user is open you app for the first time)
    int chatColor = R.drawable.user_color1;

    // Add your logic to read the shared preference and convert that last color used to a valid drawable.
    // Like chatColor = pref.getInt(indexColorSelected, R.drawable.user_color1) etc....

    // Set the color in the adapter.
    chatAdapter = newAdapter(this, mChatDataList, chatColor);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...