Search code examples
androidradio-buttonfloating-action-buttonandroid-snackbarandroid-radiogroup

How Understand Which RadioGroup Not check?


I have RecyclerView which has 60 Items and into RadioGroup have 2 RadioButton ... and I have the Fab button then clicking on it, Snack bar shows me that you have not permission to go the next page because you have checked all 60 radio group. I set Action In Snack Bar Than Understand which RadioGroup is not checked...and The TextColor Of Uncheck radio group changes. How fix it?

The method that checks if all RadioButton Check

//Select All Radio Group
  public boolean allSelected() {
    boolean allChecked = true;
    for (Question question : questionList) {
      allChecked = question.getSelectedId() != 0;


    }
    return allChecked;
  }

click on fab button

public void onResultClick(View view) {

      if (allSelected()) {
        startActivity(new Intent(MbtiQuestionActivity.this, ResultActivity.class));

      } else {
        snackbar =
          Snackbar.make(coordinator, R.string.check_all_ques_err, Snackbar.LENGTH_SHORT)

            .setAction(R.string.snack_find_unchecked_ques, new View.OnClickListener() {
              @Override
              public void onClick(View view) {

//here should right the code that uncheck radio group

              }
            });

        ViewCompat.setLayoutDirection(snackbar.getView(), ViewCompat.LAYOUT_DIRECTION_RTL);
        snackbar.show();
      }
    }

Question class

public class Question extends BaseQuestion {

  private String questTitle;   private String firstQuest;   private String secondQuest;   private int score = 0;   private int firstQuestScore = 2;   private int secondQuestScore = 3;


  private int selectedId;


  public Question(String questTitle, String firstQuest, String secondQuest) {
    this.questTitle = questTitle;
    this.firstQuest = firstQuest;
    this.secondQuest = secondQuest;

  }

  public Question(){

  }


  public String getQuestTitle() {
    return questTitle;   }

  public void setQuestTitle(String questTitle) {
    this.questTitle = questTitle;   }

  public String getFirstQuest() {
    return firstQuest;   }

  public void setFirstQuest(String firstQuest) {
    this.firstQuest = firstQuest;   }

  public String getSecondQuest() {
    return secondQuest;   }

  public void setSecondQuest(String secondQuest) {
    this.secondQuest = secondQuest;   }


  public int getScore() {
    return score;   }

  public void setScore(int questNum, int questScore) {
    this.score = ((questNum * questScore) + questNum);   }


  public int getFirstQuestScore() {
    return firstQuestScore;   }

  public void setFirstQuestScore(int firstQuestScore) {
    this.firstQuestScore = firstQuestScore;   }

  public int getSecondQuestScore() {
    return secondQuestScore;   }

  public void setSecondQuestScore(int secondQuestScore) {
    this.secondQuestScore = secondQuestScore;   }


  public void mathScore(int questNum, int questScore) {   }

  public int getSelectedId() {
    return selectedId;   }

  public void setSelectedId(int selectedId) {
    this.selectedId = selectedId;   }


}

Fab in xml

<android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:src="@drawable/check_outline"
        app:fabSize="normal"
        android:onClick="@{handlers::onResultClick}"
        android:clickable="true"
        android:focusable="true"/>

and I use DataBinding ... thanks.

Click On "بررسی" and The TextColor or CardView Background be changed !(THe RadioGroup not Check!)

enter image description here

log error :

 Process: mbtitest.kiars.me.mbti, PID: 19757
    java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
        at mbtitest.kiars.me.mbti.databinding.QuesItemRowBinding.executeBindings(QuesItemRowBinding.java:196)
        at android.databinding.ViewDataBinding.executeBindingsInternal(ViewDataBinding.java:437)
        at android.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:409)
        at android.databinding.ViewDataBinding$7.run(ViewDataBinding.java:194)
        at android.databinding.ViewDataBinding$8.doFrame(ViewDataBinding.java:286)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
        at android.view.Choreographer.doCallbacks(Choreographer.java:676)
        at android.view.Choreographer.doFrame(Choreographer.java:603)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:859)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:168)
        at android.app.ActivityThread.main(ActivityThread.java:5885)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)

Solution

  • row.xml

    <data>
    
        <variable
            name="model"
            type="com.innovanathinklabs.sample.data.TestViewModel"/>
    
    </data>
    
    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:cardBackgroundColor="@{question.selected ? @color/colorAccent : @android:color/transparent}"
        />
    

    Model.java

    import com.yourpackage.BR;
    public class Question extends BaseObservable {
        private boolean selected;
    
        @Bindable
        public boolean isSelected() {
            return selected;
        }
    
        public void setSelected(boolean selected) {
            this.selected = selected;
            notifyPropertyChanged(BR.selected);
        }
    }
    

    Show background

    public void setErrorBackground() {
        for (Question question : questionList) {
            question.setSelected(question.getSelectedId() != 0);
        }
    }
    
        Snackbar.make(coordinator, R.string.check_all_ques_err, Snackbar.LENGTH_SHORT)
    
            .setAction(R.string.snack_find_unchecked_ques, new View.OnClickListener() {
              @Override
              public void onClick(View view) {
               setErrorBackground(); //call this
              }
            });
    

    To remove error background, call this method from anywhere

    public void removeErrorBackground() {
        for (Question question : questionList) {
            question.setSelected(false);
        }
    }
    

    Update

    If you want to remove background after user checks, do this

    app:cardBackgroundColor="@{model.selected &amp;&amp; model.selectedId == 0  ? @color/colorAccent : @android:color/transparent}"
    

    here &amp;&amp; means &&

    Update 2

    Remove selected field.

    public class Question extends BaseObservable {
        private boolean showErrorBackground;
    
        @Bindable
        public boolean isShowErrorBackground() {
            return showErrorBackground;
        }
    
        public void setShowErrorBackground(boolean showErrorBackground) {
            this.showErrorBackground = showErrorBackground;
            notifyPropertyChanged(BR.selected);
        }
    }
    

    in layout

        app:cardBackgroundColor="@{model.showErrorBackground &amp;&amp; model.selectedId == 0  ? @color/colorAccent : @android:color/transparent}"
    

    in Activity

    private void showHideErrorBackground(boolean show) {
        for (Question question : list) {
            question.setShowErrorBackground(show);
        }
        adapter.notifyDataSetChanged();
    }
    

    in onClick of SnakeBar

    showHideErrorBackground(true);
    

    Update

    public class Question extends BaseObservable {
        private boolean showErrorBackground;
        private int selectedId;
    
        @Bindable
        public boolean isShowErrorBackground() {
            return showErrorBackground;
        }
    
        public void setShowErrorBackground(boolean showErrorBackground) {
            this.showErrorBackground = showErrorBackground;
            notifyPropertyChanged(BR.selected);
        }
    
        @Bindable
        public int getSelectedId() {
            return selectedId;
        }
    
        public void setSelectedId(int selectedId) {
            this.selectedId = selectedId;
            notifyPropertyChanged(BR.selectedId);
        }
    }
    

    We have to make selectedId bindable because we want to invoke its uses when it is changed.