Ví dụ với ChipGroup và các Chip Entry

Xem thêm các chuyên mục:

1- Mục tiêu của ví dụ

Trong bài học này tôi sẽ hướng dẫn bạn tạo một ứng dụng Android sử dụng ChipGroupChip Entry. Đây chỉ là một ví dụ nhỏ, vì vậy sẽ không có nhiều giải thích về ChipGroupChip, nếu muốn có một giải thích đầy đủ hãy tham khảo bài viết dưới đây:
Đặc điểm của một Chip Entry là nó có thể check (checkable) và nó biểu tượng đóng (close Icon), vì vậy nó thích hợp cho một số ứng dụng tương tự như ví dụ trong bài viết này.

2- Ví dụ ChipGroup và Chip Entry

Trên Android Studio tạo mới một project:
  • File > New > New Project > Empty Activity
    • Name: ChipEntryGroupExample
    • Package name: org.o7planning.chipentrygroupexample
    • Language: Java
Đầu tiên, bạn cần cài đặt thư viện Chip vào project của bạn:
Hoặc bạn có thể thêm thư viện chứa thành phần Chip vào project của bạn một cách thủ công:
build.gradle (Module app)
dependencies {
    
    ...
    implementation 'com.google.android.material:material:1.1.0'
}
Nhấn phải chuột vào thư mục "layout" và chọn:
  • New > Layout Resource File
  • File name: layout_chip_entry.xml
"Layout Resource File" cho phép bạn định nghĩa một phần của giao diện người dùng (User interface), trong ví dụ này nó rất đơn giản, chỉ bao gồm một phần tử Chip Entry.
layout_chip_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.chip.Chip
     xmlns:android="http://schemas.android.com/apk/res/android"
     style="@style/Widget.MaterialComponents.Chip.Entry"
     android:theme="@style/Theme.MaterialComponents.Light"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     />
Giao diện của ứng dụng:
Nếu bạn quan tâm tới các bước để thiết kế giao diện của ứng dụng này hãy xem phần phụ lục phía cuối bài viết.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editText_keyword"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="17dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:ems="10"
        android:inputType="textPersonName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="Add"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editText_keyword" />

    <com.google.android.material.chip.ChipGroup
        android:id="@+id/chipGroup"
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:background="#F3EEEE"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_add" />

    <Button
        android:id="@+id/button_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="18dp"
        android:text="Show Selections"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/chipGroup" />

</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
package org.o7planning.chipentrygroupexample;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.material.chip.Chip;
import com.google.android.material.chip.ChipGroup;

public class MainActivity extends AppCompatActivity {

    private EditText editTextKeyword;
    private ChipGroup chipGroup;
    private Button buttonAdd;
    private Button buttonShow;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.editTextKeyword = (EditText) this.findViewById(R.id.editText_keyword);
        this.chipGroup = (ChipGroup) this.findViewById(R.id.chipGroup);
        this.buttonAdd = (Button) this.findViewById(R.id.button_add);
        this.buttonShow = (Button) this.findViewById(R.id.button_show);

        this.buttonAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addNewChip();
            }
        });
        this.buttonShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSelections();
            }
        });
    }


    private void addNewChip() {
        String keyword = this.editTextKeyword.getText().toString();
        if (keyword == null || keyword.isEmpty()) {
            Toast.makeText(this, "Please enter the keyword!", Toast.LENGTH_LONG).show();
            return;
        }

        try {
            LayoutInflater inflater = LayoutInflater.from(this);

            // Create a Chip from Layout.
            Chip newChip = (Chip) inflater.inflate(R.layout.layout_chip_entry, this.chipGroup, false);
            newChip.setText(keyword);

            //
            // Other methods:
            //
            // newChip.setCloseIconVisible(true);
            // newChip.setCloseIconResource(R.drawable.your_icon);
            // newChip.setChipIconResource(R.drawable.your_icon);
            // newChip.setChipBackgroundColorResource(R.color.red);
            // newChip.setTextAppearanceResource(R.style.ChipTextStyle);
            // newChip.setElevation(15);

            this.chipGroup.addView(newChip);

            // Set Listener for the Chip:
            newChip.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    handleChipCheckChanged((Chip) buttonView, isChecked);
                }
            });

            newChip.setOnCloseIconClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    handleChipCloseIconClicked((Chip) v);
                }
            });


            this.editTextKeyword.setText("");

        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(this, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }

    // User click on "Show Selections" button.
    private void showSelections()  {
         int count = this.chipGroup.getChildCount();

         String s = null;
         for(int i=0;i< count; i++) {
             Chip child = (Chip) this.chipGroup.getChildAt(i);

             if(!child.isChecked()) {
                 continue;
             }

             if(s == null)  {
                 s = child.getText().toString();
             } else {
                 s += ", " + child.getText().toString();
             }
         }
         Toast.makeText(this, s, Toast.LENGTH_LONG).show();
    }

    // User close a Chip.
    private void handleChipCloseIconClicked(Chip chip) {
        ChipGroup parent = (ChipGroup) chip.getParent();
        parent.removeView(chip);
    }

    // Chip Checked Changed
    private void handleChipCheckChanged(Chip chip, boolean isChecked) {
    }
}

3- Phụ lục: Thiết kế giao diện

Các bước thiết kế giao diện ứng dụng:
Sét đặt ID, Text, Background cho các thành phần trên giao diện:

Xem thêm các chuyên mục: