343N 343N - 12 days ago 5
Android Question

ToggleButton in ListView being inconsistent with isChecked setting

So I have a button set in a listview to save in sharedpreferences its checked state when checked/unchecked and then when it's loading the view it'll automatically set the check state based on whether it's saved-as checked or un-checked, but some seem to un-check themselves or never toggle at all. It's fairly inconsistent.

Here's my ListViewAdapter

public class deityListAdapter extends ArrayAdapter<deities> {

Context context;
int layoutResourceId;
deities data[] = null;

public deityListAdapter(Context context, int layoutResourceId, deities data[]) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View ListItem = convertView;
Holder holder;

if (ListItem == null) {

LayoutInflater inflater = ((Activity) context).getLayoutInflater();
ListItem = inflater.inflate(layoutResourceId, parent, false);

holder = new Holder();
// holder.description = (TextView) ListItem.findViewById(R.id.deityDesc);
holder.banner = (ImageView) ListItem.findViewById(R.id.deityBanner);
holder.website = (Button) ListItem.findViewById(R.id.deityWebsite);
holder.active = (ToggleButton) ListItem.findViewById(R.id.isActiveButtonToggle);
// holder.background = (RelativeLayout) ListItem.findViewById(R.id.listItemBG);
holder.highlight = (ImageView) ListItem.findViewById(R.id.highlight);
// holder.highlight2 = (ImageView) ListItem.findViewById(R.id.highlight2);
holder.title = (TextView) ListItem.findViewById(R.id.titleText);

ListItem.setTag(holder);

} else {
holder = (Holder) ListItem.getTag();
}
final deities deity = data[position];

View.OnClickListener holderListener = new View.OnClickListener() {
public void onClick(View v) {
WebView webView = (WebView) ((Activity) context).findViewById(R.id.webView);
webView.setVisibility(View.VISIBLE);
webView.loadUrl(deity.url);
}
};

CompoundButton.OnCheckedChangeListener ToggleButtonListener = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
SharedPreferences sharedPref = ((Activity) context).getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor prefeditor = sharedPref.edit();
final CompoundButton Button = buttonView;
final RelativeLayout r = (RelativeLayout) ((ViewGroup) Button.getParent()).getParent();
if (isChecked) {
deity.active = true;
prefeditor.putBoolean(Integer.toString(deity.id), true);
prefeditor.apply();
ViewGroup ListItem = (ViewGroup) buttonView.getParent();


ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), Color.parseColor("#ce5a5a"),Color.parseColor("#2e7d32"));
colorAnimation.setDuration(100);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {

ImageView sideThing1 = (ImageView) r.findViewById(R.id.highlight);
// ImageView sideThing2 = (ImageView) r.findViewById(R.id.highlight2);
sideThing1.setBackgroundColor((int) animation.getAnimatedValue());
// sideThing2.setBackgroundColor((int) animation.getAnimatedValue());
Button.setBackgroundColor((int) animation.getAnimatedValue());

}
});
colorAnimation.start();

} else {
deity.active = false;
prefeditor.putBoolean(Integer.toString(deity.id), false);
prefeditor.apply();
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), Color.parseColor("#2e7d32"),Color.parseColor("#ce5a5a"));
colorAnimation.setDuration(250);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
ImageView sideThing1 = (ImageView) r.findViewById(R.id.highlight);
// ImageView sideThing2 = (ImageView) r.findViewById(R.id.highlight2);
sideThing1.setBackgroundColor((int) animation.getAnimatedValue());
// sideThing2.setBackgroundColor((int) animation.getAnimatedValue());
Button.setBackgroundColor((int) animation.getAnimatedValue());
}
});
colorAnimation.start();
}
}
};

SharedPreferences sharedPref = ((Activity) context).getPreferences(Context.MODE_PRIVATE);
deity.active = sharedPref.getBoolean(Integer.toString(deity.id), false);
if (deity.active) {
holder.active.setChecked(true);
holder.active.setBackgroundColor(Color.parseColor("#2e7d32"));
holder.highlight.setBackgroundColor(Color.parseColor("#2e7d32"));
// holder.highlight2.setBackgroundColor(Color.parseColor("#2e7d32"));


} else {
holder.active.setChecked(false);
holder.active.setBackgroundColor(Color.parseColor("#ce5a5a"));
holder.highlight.setBackgroundColor(Color.parseColor("#ce5a5a"));
// holder.highlight2.setBackgroundColor(Color.parseColor("#ce5a5a"));
}


holder.active.setOnCheckedChangeListener(ToggleButtonListener);
holder.website.setOnClickListener(holderListener);
holder.banner.setImageResource(deity.banner);
// holder.description.setText(deity.description);
holder.banner.setBackgroundColor(Color.parseColor("#616161"));
// holder.description.setText(deity.url);
holder.title.setText(deity.title + " " + deity.active);
return ListItem;

}
static class Holder {

TextView title;
ImageView banner;
Button website;
ToggleButton active;
ImageView highlight;



}

}


This is what I mean by inconsistent (click me, it's a video)

Notice how some revert back/don't save?

A day later, I still can't figure it out.

Answer

Try this:

@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
    View ListItem = convertView;
    Holder holder;

    if (ListItem == null) {

        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        ListItem = inflater.inflate(layoutResourceId, parent, false);

        holder = new Holder();
        //            holder.description = (TextView) ListItem.findViewById(R.id.deityDesc);
        holder.banner = (ImageView) ListItem.findViewById(R.id.deityBanner);
        holder.website = (Button) ListItem.findViewById(R.id.deityWebsite);
        holder.active = (ToggleButton) ListItem.findViewById(R.id.isActiveButtonToggle);
        //            holder.background = (RelativeLayout) ListItem.findViewById(R.id.listItemBG);
        holder.highlight = (ImageView) ListItem.findViewById(R.id.highlight);
        //            holder.highlight2 = (ImageView) ListItem.findViewById(R.id.highlight2);
        holder.title = (TextView) ListItem.findViewById(R.id.titleText);

        ListItem.setTag(holder);

    } else {
        holder = (Holder) ListItem.getTag();
    }
    final deities deity = data[position];

    View.OnClickListener holderListener = new View.OnClickListener() {
        public void onClick(View v) {
            WebView webView = (WebView)((Activity) context).findViewById(R.id.webView);
            webView.setVisibility(View.VISIBLE);
            webView.loadUrl(deity.url);
        }
    };

    CompoundButton.OnCheckedChangeListener ToggleButtonListener = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            int position = (int) buttonView.getTag();

            final deities deity = data[position];

            SharedPreferences sharedPref = ((Activity) context).getPreferences(Context.MODE_PRIVATE);
            SharedPreferences.Editor prefeditor = sharedPref.edit();
            final CompoundButton Button = buttonView;
            final RelativeLayout r = (RelativeLayout) Button.getParent().getParent();

            deity.active = isChecked;
            prefeditor.putBoolean(Integer.toString(deity.id), isChecked);
            prefeditor.apply();

            int startColor = isChecked ? Color.parseColor("#ce5a5a") : Color.parseColor("#ce5a5a");
            int endColor = isChecked ? Color.parseColor("#2e7d32") : Color.parseColor("#2e7d32");

            ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), startColor, endColor);
            colorAnimation.setDuration(100);
            colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {

                    ImageView sideThing1 = (ImageView) r.findViewById(R.id.highlight);
                    //                            ImageView sideThing2 = (ImageView) r.findViewById(R.id.highlight2);
                    sideThing1.setBackgroundColor((int) animation.getAnimatedValue());
                    //                            sideThing2.setBackgroundColor((int) animation.getAnimatedValue());
                    Button.setBackgroundColor((int) animation.getAnimatedValue());

                }
            });
            colorAnimation.start();

            notifyDataSetChanged();
        }
    };

    SharedPreferences sharedPref = ((Activity) context).getPreferences(Context.MODE_PRIVATE);
    deity.active = sharedPref.getBoolean(Integer.toString(deity.id), false);

    holder.active.setChecked(deity.active);

    if (deity.active) {
        holder.active.setBackgroundColor(Color.parseColor("#2e7d32"));
        holder.highlight.setBackgroundColor(Color.parseColor("#2e7d32"));
    } else {
        holder.active.setBackgroundColor(Color.parseColor("#ce5a5a"));
        holder.highlight.setBackgroundColor(Color.parseColor("#ce5a5a"));
    }

    holder.active.setTag(position);

    holder.active.setOnCheckedChangeListener(ToggleButtonListener);
    holder.website.setOnClickListener(holderListener);
    holder.banner.setImageResource(deity.banner);
    //        holder.description.setText(deity.description);
    holder.banner.setBackgroundColor(Color.parseColor("#616161"));
    //        holder.description.setText(deity.url);
    holder.title.setText(deity.title + " " + deity.active);
    return ListItem;
}

PS: I tried to fix the problem without a lot of changes so this might not be the best answer

Comments