Chip Group OnCheckedChangeListener() not triggered

烂漫一生 提交于 2019-11-30 04:21:04

问题


I'm trying to make a recyclerview filter based ChipGroup & Chip

I'm use fragment on my app, so, the fragment who contain the RecyclerView contain a frameLayout who inflate the ChipGroup filter fragment

I'm trying to trigger a listener when the user unselect all chip inside ChipGroup (I've already put listener on chip for trigger when chip are checked by user)

I've already put some listener on chipgroup but no one are trigered

FilterFragment.java

public class FilterFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
public ChipGroup chipGroup;

// TODO: Rename and change types of parameters
public View.OnClickListener chipClickListener;

private OnFragmentInteractionListener mListener;

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


public static FilterFragment newInstance(View.OnClickListener 
param1) {
    CoachFilterFragment fragment = new CoachFilterFragment();
    Bundle args = new Bundle();

    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {

    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup 
container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_filter, 
container, false);
    this.chipGroup = view.findViewById(R.id.chipGroup);
    for(Skill skill : ((MainActivity)getContext()).api.skills){

        Chip chip = new Chip(getContext());
        chip.setId(skill.getId());


        chip.setText(skill.getName());
        chip.setOnClickListener(chipClickListener);
        chip.setCheckable(true);
        chipGroup.addView(chip);

    }

    chipGroup.setOnCheckedChangeListener((chipGroup, id) -> {
      Log.d("test","ok");
    });


    return view;
}

public void onButtonPressed(Uri uri) {
    if (mListener != null) {
        mListener.onFragmentInteraction(uri);
    }
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);

}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}



public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    void onFragmentInteraction(Uri uri);
  }
}

FilterFragment.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 
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="wrap_content"
tools:context=".Fragment.FilterFragment">

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.chip.ChipGroup
        android:id="@+id/chipGroup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

       </com.google.android.material.chip.ChipGroup>
   </androidx.constraintlayout.widget.ConstraintLayout>

</FrameLayout>

Someone have any idea why any listener are not triggered by my ChipGroup?Maybe I'm missing some parameter or something?


回答1:


Your code is fine the only issue is that setOnCheckedChangeListener() only work when your ChipGroup is for singleSelection

Read this documentation of ChipGroup

setOnCheckedChangeListener()

  • Register a callback to be invoked when the checked chip changes in this group.
  • This callback is only invoked in single selection mode.

ALSO READ

Handling Checked Chips

Call setOnCheckedChangeListener(OnCheckedChangeListener) to register a callback to be invoked when the checked chip changes in this group. This callback is only invoked in single selection mode.

if you want use setOnCheckedChangeListener() of ChipGroup than you need to make app:singleSelection="true"

UPDATE

based on your below comment i have added sample code to manage to handle when ChipGroup selection

SAMPLE CODE for maintain selection in ChipGroup

Layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.chip.ChipGroup
            android:id="@+id/chipGroup"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginBottom="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            >

        </com.google.android.material.chip.ChipGroup>
    </androidx.constraintlayout.widget.ConstraintLayout>

    <Button
        android:layout_width="match_parent"
        android:text="Get Result"
        android:id="@+id/btnShowResult"
        android:layout_gravity="bottom"
        android:layout_height="wrap_content" />
</LinearLayout>

Activity code

public class Main3Activity extends AppCompatActivity {

    public ChipGroup chipGroup;
    public Button btnShowResult;
    public ArrayList<Boolean> booleanArrayList = new ArrayList<>();

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

        chipGroup = findViewById(R.id.chipGroup);
        btnShowResult = findViewById(R.id.btnShowResult);


        btnShowResult.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                for (int i = 0; i < booleanArrayList.size(); i++) {
                    Log.e("RESULT", i + " :" + booleanArrayList.get(i));
                }
            }
        });

        for (int i = 0; i < 5; i++) {

            Chip chip = new Chip(this);
            chip.setId(i);
            chip.setTag(i);

            booleanArrayList.add(false);
            chip.setText("Chip No : " + i);
            chip.setCheckable(true);

            chip.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

                    int tag = (int) compoundButton.getTag();
                    booleanArrayList.set(tag, b);

                }
            });
            chipGroup.addView(chip);

        }

        chipGroup.invalidate();


        chipGroup.setOnCheckedChangeListener(new ChipGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(ChipGroup chipGroup, int i) {

                Chip chip = chipGroup.findViewById(i);


                if (chip != null)
                    Toast.makeText(getApplicationContext(), "Chip is " + chip.getText().toString(), Toast.LENGTH_SHORT).show();

                Log.e("OnCheckedChangeListener", "Called");
            }
        });

    }

    ChipGroup.OnCheckedChangeListener onCheckedChangeListener = new ChipGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(ChipGroup chipGroup, int i) {

        }
    };

}

For more information please check below articles

  • Chips: Material Components for Android
  • Android P: Chips and ChipGroup
  • Exploring the v28 Android Design Support Library Additions



回答2:


Chip Click listener will only work if the single selection was set to true in chipGroup.

app:singleSelection="true"

If you're using the style like below, then make sure it was also given to every individual chip as well.

style="@style/Widget.MaterialComponents.Chip.Choice"

like this:

<com.google.android.material.chip.ChipGroup
                android:id="@+id/chip_group"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_marginEnd="10dp"
                app:singleSelection="true"
                style="@style/Widget.MaterialComponents.Chip.Choice">

            <com.google.android.material.chip.Chip
                    android:id="@+id/chip_2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    style="@style/Widget.MaterialComponents.Chip.Choice"
                    android:text="@string/announcements"
                    android:textAppearance="@style/ChipThemeBold"/>
            <com.google.android.material.chip.Chip
                    android:id="@+id/chip_3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    style="@style/Widget.MaterialComponents.Chip.Choice"
                    android:text="@string/fyi"
                    android:textAppearance="@style/ChipThemeBold"/>
            <com.google.android.material.chip.Chip
                    android:id="@+id/chip_4"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    style="@style/Widget.MaterialComponents.Chip.Choice"
                    android:text="@string/heartbeat"
                    android:textAppearance="@style/ChipThemeBold"  />
            <com.google.android.material.chip.Chip
                    android:id="@+id/chip_5"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    style="@style/Widget.MaterialComponents.Chip.Choice"
                    android:text="@string/pitch"
                    android:textAppearance="@style/ChipThemeBold"  />
            <com.google.android.material.chip.Chip
                    android:id="@+id/chip_6"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    style="@style/Widget.MaterialComponents.Chip.Choice"
                    android:text="@string/question"
                    android:textAppearance="@style/ChipThemeBold" 
                    android:layout_marginEnd="15dp" />

        </com.google.android.material.chip.ChipGroup>



回答3:


It works like this way.

// com.google.android.material.chip.ChipGroup
app:singleSelection="true"

// com.google.android.material.chip.Chip (R.layout.chip)
style="@style/Widget.MaterialComponents.Chip.Choice"

// Inflate instead of NEW instance
val chip = layoutInflater.inflate(R.layout.chip, chipGroup, false) as Chip
chip.text = "Text"
chipGroup.addView(chip)

// setOnCheckedChangeListener
chipGroup.setOnCheckedChangeListener { group, checkedId ->
    // The same checked chip
    if (checkedId == -1) {
        return@setOnCheckedChangeListener
    }

    // TODO
}



回答4:


i have same issue, but it's not relate to ChipGroup because i put the ChipGroup in wrong place like this:

<androidx.constraintlayout.widget.ConstraintLayout>

   <com.google.android.material.chip.ChipGroup />

   <other full screen view />
<androidx.constraintlayout.widget.ConstraintLayout/>

it makes my ChipGroup unfocusable, so just move the ChipGroup to the bottom of parent view

<androidx.constraintlayout.widget.ConstraintLayout>
   <other full screen view />

   <-- change here -->
   <com.google.android.material.chip.ChipGroup />
<androidx.constraintlayout.widget.ConstraintLayout/>

and it works, hope it helps




回答5:


I will suggest don't make use of recyclerview with chips if you want horizontal scrolling because you got HorizontalScrollView and it works quite well with chipgroup:

Based on Nilesh Rathod's Answer. To add chips dynamically you need following code:

Activity File Code:

String[] fileNameChip = getIntent().getStringArrayExtra(Constants.CHIPS_NAME_ARRAY);

        for (final String chipName : fileNameChip) {
             LayoutInflater layoutInflater = getLayoutInflater();
             Chip chip = (Chip) 
             layoutInflater.inflate(R.layout.cat_chip_group_item_choice, chipGroup, false);
             chip.setText(chipName);
             chip.setId(i); //HERE SET ID THAT WILL BE CHECKED_ID ON setOnCheckedChangeListener

             chip.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                     Log.d(TAG, "onClick: " + chipName );
                     }
                  });
                  chipGroup.addView(chip);
              }  
              chipGroup.setOnCheckedChangeListener(new ChipGroup.OnCheckedChangeListener() {
                   @Override
                   public void onCheckedChanged(ChipGroup group, int checkedId) {
                          Log.d(TAG, "onCheckedChanged: " + checkedId);
                       }
                    });

Activity XML FILE:

<LinearLayout 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"
android:orientation="vertical">

<HorizontalScrollView
    android:layout_width="match_parent"
    android:scrollbars="none"
    android:layout_height="wrap_content">

    <com.google.android.material.chip.ChipGroup
        android:id="@+id/chip_group_code_files"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:singleLine="true"
        app:singleSelection="true" />
</HorizontalScrollView>

cat_chip_group_item_choice.xml:(Specify chip type:Choice,filter,Action,Normal)

<?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.Choice"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>


来源:https://stackoverflow.com/questions/53477424/chip-group-oncheckedchangelistener-not-triggered

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!