1

I'have three class, in typo fragment i use my custom class StyleAdaptation and SizeAndStyleAdaptation (and SizeAdaptation but forget this one) is the same class (SizeAndStyle implement just a spinner for the font size) and they extends a CardView.

And in StyleAdaptation i have another custom view, StyleAndColor where i have four button for bold, italic, underline and a last one for the color.

So i have a problem when i set the upper_style for example i set bold if i change fragment and return here the value is not saved. But if i change the ponc_style after change fragment and return, if i was set bold, the both (ponc_style and upper_style is set bold) the problem comes from the id's.

And i don't know how assign unique id in this case with some views on childS.

TypoFragment.java is my root fragment when i call the others class.

    public class TypoFragment extends Fragment {

    private SizeAdaptation word_space;
    private SizeAdaptationModel current_word_space = new SizeAdaptationModel();
    private SizeAdaptation letter_space;
    private SizeAdaptationModel current_letter_space = new SizeAdaptationModel();
    private SizeAdaptation line_space;
    private SizeAdaptationModel current_line_space = new SizeAdaptationModel();
    private SizeAndStyleAdaptation upper_style;
    private SizeAndStyleAdaptationModel current_upper_style = new SizeAndStyleAdaptationModel();
    private StyleAdaptation ponc_style;
    private StyleAdaptationModel current_ponc_style = new StyleAdaptationModel();

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_typo, container, false);
        return (rootView);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        word_space = (SizeAdaptation)view.findViewById(R.id.word_space);
        letter_space = (SizeAdaptation)view.findViewById(R.id.letter_space);
        line_space = (SizeAdaptation)view.findViewById(R.id.line_space);
        upper_style = (SizeAndStyleAdaptation)view.findViewById(R.id.upper_style);
        ponc_style = (StyleAdaptation)view.findViewById(R.id.ponc_style);

        word_space.setListener(new SizeAdaptation.SizeAdaptationListener() {
            @Override
            public void onSizeSelected(float size) {
                current_word_space.setSize(size);
            }
        });

        letter_space.setListener(new SizeAdaptation.SizeAdaptationListener() {
            @Override
            public void onSizeSelected(float size) {
                current_letter_space.setSize(size);
            }
        });

        line_space.setListener(new SizeAdaptation.SizeAdaptationListener() {
            @Override
            public void onSizeSelected(float size) {
                current_line_space.setSize(size);
            }
        });

        upper_style.setListener(new SizeAndStyleAdaptation.SizeAndStyleAdaptationListener() {
            @Override
            public void onSizeSelected(int size) {
                current_upper_style.setSize(size);
            }

            @Override
            public void onStyleChanged(int style) {
                current_upper_style.setStyle(style);
            }

            @Override
            public void onUnderlineChanged(boolean underline) {
                current_upper_style.setUnderline(underline);
            }

            @Override
            public void onColorChanged(int color) {
                current_upper_style.setColor(color);
            }
        });

        ponc_style.setListener(new StyleAdaptation.StyleAdaptationListener() {
            @Override
            public void onStyleChanged(int style) {
                current_ponc_style.setStyle(style);
            }

            @Override
            public void onUnderlineChanged(boolean underline) {
                current_ponc_style.setUnderline(underline);
            }

            @Override
            public void onColorChanged(int color) {
                current_ponc_style.setColor(color);
            }
        });

    }

    @Override
    public void onResume() {
        super.onResume();
    }
}

fragment_typo.xml

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
        android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <com.aidodys.profilesCreation.Views.SizeAdaptation
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/adaptation"
                app:size_adaptation_title="@string/word_space"
                app:size_adaptation_size_values="@array/word_and_letter_spaces"
                android:id="@+id/word_space" />

            <com.aidodys.profilesCreation.Views.SizeAdaptation
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/adaptation"
                app:size_adaptation_title="@string/letter_space"
                app:size_adaptation_size_values="@array/word_and_letter_spaces"
                android:id="@+id/letter_space" />

            <com.aidodys.profilesCreation.Views.SizeAdaptation
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/adaptation"
                app:size_adaptation_title="@string/line_space"
                app:size_adaptation_size_values="@array/line_spaces"
                android:id="@+id/line_space" />

            <com.aidodys.profilesCreation.Views.SizeAndStyleAdaptation
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/adaptation"
                app:ss_adaptation_size_values="@array/fonts_sizes"
                app:ss_adaptation_title="@string/upper_style"
                android:id="@+id/upper_style" />

            <com.aidodys.profilesCreation.Views.StyleAdaptation
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/adaptation"
                app:style_adaptation_title="@string/ponc_style"
                android:id="@+id/ponc_style" />
        </LinearLayout>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/profiles_creation_next_step"
            android:id="@+id/next"
            android:layout_marginBottom="25dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true" />
    </RelativeLayout>

</FrameLayout>

StyleAdaptation.java is a class where i extends a cardview for display some fields for style adaptations

    public class StyleAdaptation extends CardView implements IAdaptation {

    public interface StyleAdaptationListener {
        void onStyleChanged(int style);
        void onUnderlineChanged(boolean underline);
        void onColorChanged(int color);
    }

    private StyleAdaptationListener listener;
    private StyleAndColor styleAndColor;
    private TextView titleView;
    private String title;
    private int style;
    private int color;
    private boolean underline;
    private AdaptationDataType dataType = AdaptationDataType.STYLE;
    private AdaptationType adaptationType;

    public StyleAdaptation(Context context) {
        super(context);
        init();
    }

    public StyleAdaptation(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.StyleAdaptation);
        title = a.getString(R.styleable.StyleAdaptation_style_adaptation_title);
        a.recycle();
        init();
    }

    private void init() {
        LayoutInflater inflater = (LayoutInflater)
                getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        inflater.inflate(R.layout.style_adaptation, this);

        styleAndColor = (StyleAndColor) findViewById(R.id.adaptation_style);
        styleAndColor.setListener(new StyleAndColor.StyleAndColorListener() {
            @Override
            public void onStyleChanged(int styleSelected) {
                style = styleSelected;
                listener.onStyleChanged(style);
            }

            @Override
            public void onUnderlineChanged(boolean underlined) {
                underline = underlined;
                listener.onUnderlineChanged(underline);
            }

            @Override
            public void onColorChanged(int colorSelected) {
                color = colorSelected;
                listener.onColorChanged(color);
            }
        });
        titleView = (TextView) findViewById(R.id.adaptation_title);
        titleView.setText(title);

    }

    @Override
    public AdaptationDataType getDataType() {
        return(this.dataType);
    }

    @Override
    public AdaptationType getAdaptationType() {
        return(this.adaptationType);
    }

    @Override
    public String getAdaptationName() {
        return(this.title);
    }

    @Override
    public String getFirstName() {
        return null;
    }

    @Override
    public String getSecondName() {
        return null;
    }

    @Override
    public Object getAdaptation() {
        return(this);
    }

    @Override
    public boolean isUnderlined() {
        return(underline);
    }

    @Override
    public int getStyle() {
        return 0;
    }

    @Override
    public int getColor() {
        return 0;
    }

    @Override
    public float getSize() {
        return 0;
    }

    public void setListener(StyleAdaptationListener listener) {
        this.listener = listener;
    }
}

style_adaptation.xml

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/adaptation_cw">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/adaptation_title"
        android:id="@+id/adaptation_title" />

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/adaptation_fields">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/cross"
            style="@style/adaptation_add"
            android:id="@+id/add" />

        <com.aidodys.profilesCreation.Views.StyleAndColor
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/adaptation_style"
            style="@style/adaptation_style_sc" />
    </RelativeLayout>
    </RelativeLayout>

And StyleAndColor.java extends RelativeLayout where i have just four buttons for bold, italic, underline, and a last one for set the text color.

    public class StyleAndColor extends RelativeLayout {

    public interface StyleAndColorListener {
        public void onStyleChanged(int styleSelected);
        public void onUnderlineChanged(boolean underlined);
        public void onColorChanged(int colorSelected);
    }

    private StyleAndColorListener listener = null;

    private ToggleButton bold;
    private ToggleButton italic;
    private ToggleButton underline;
    private ImageView    colorButton;
    private int          colorSelected;
    private int          styleSelected;
    private boolean underlined;

    public StyleAndColor(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public StyleAndColor(Context context) {
        super(context);
        init();
    }

    private void init() {
        LayoutInflater inflater = (LayoutInflater)
                getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        inflater.inflate(R.layout.style_and_color, this);

        bold = (ToggleButton)findViewById(R.id.bold);
        italic = (ToggleButton)findViewById(R.id.italic);
        underline = (ToggleButton)findViewById(R.id.underline);
        colorButton = (ImageView)findViewById(R.id.colorButton);
        colorSelected = 0xFF000000;
        colorButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm = ((FragmentActivity)getContext()).getSupportFragmentManager();
                final ColorPickerFragment colorPicker = new ColorPickerFragment();
                colorPicker.setListener(new ColorPickerFragment.ColorPickerListener() {
                    @Override
                    public void onColorSelected(int colorSelected) {
                        setColorSelected(colorSelected);
                        colorButton.setColorFilter(getColorSelected());
                        listener.onColorChanged(getColorSelected());
                    }
                });
                colorPicker.show(fm, "fragment_color_picker");
            }
        });

        bold.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked) {
                    if(italic.isChecked())
                        styleSelected = Typeface.BOLD_ITALIC;
                    else
                        styleSelected = Typeface.BOLD;
                } else {
                    if(italic.isChecked())
                        styleSelected = Typeface.ITALIC;
                    else
                        styleSelected = Typeface.NORMAL;
                }
                listener.onStyleChanged(styleSelected);
            }
        });

        italic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked) {
                    if(bold.isChecked())
                        styleSelected = Typeface.BOLD_ITALIC;
                    else
                        styleSelected = Typeface.ITALIC;
                } else {
                    if(bold.isChecked())
                        styleSelected = Typeface.BOLD;
                    else
                        styleSelected = Typeface.NORMAL;
                }
                listener.onStyleChanged(styleSelected);
            }
        });

        underline.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                underlined = isChecked;
                listener.onUnderlineChanged(underlined);
            }
        });
    }

    public void setColorSelected(int colorSelected) {
        this.colorSelected = colorSelected;
    }

    public int getColorSelected() {
        return colorSelected;
    }

    public int getStyleSelected() {
        return styleSelected;
    }

    public boolean isUnderlined() {
        return underlined;
    }

    public void setListener(StyleAndColorListener listener) {
        this.listener = listener;
    }

    public void setColorButtonColor(int color) {
        ImageView colorButton = (ImageView)findViewById(R.id.colorButton);
        colorButton.setColorFilter(color);
    }
}

And style_and_color.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content" android:layout_height="wrap_content">

    <ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/toggle_background_color"
        android:textOn="@string/bold"
        android:textOff="@string/bold"
        android:textColor="@color/toggle_color"
        android:id="@+id/bold" />
    <ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/toggle_background_color"
        android:textOn="@string/italic"
        android:textOff="@string/italic"
        android:textColor="@color/toggle_color"
        android:layout_toEndOf="@+id/bold"
        android:layout_toRightOf="@+id/bold"
        android:id="@+id/italic"/>
    <ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/toggle_background_color"
        android:textOn="@string/underline"
        android:textOff="@string/underline"
        android:textColor="@color/toggle_color"
        android:layout_toEndOf="@+id/italic"
        android:layout_toRightOf="@+id/italic"
        android:id="@+id/underline" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/palette"
        android:id="@+id/colorButton"
        android:layout_toEndOf="@+id/underline"
        android:layout_toRightOf="@+id/underline"
        />

</RelativeLayout>

a screenshot of typo fragment :

typo fragment screenshot

Maxime Limone
  • 121
  • 11
  • Thank you , i have an exception : android.view.InflateException: Binary XML file line #40: Binary XML file line #40: Error inflating class com.aidodys.profilesCreation.Views.SizeAndStyleAdaptation – Maxime Limone May 12 '16 at 08:50

1 Answers1

0

You can manually save and restore a state of StyleAdaptation

I've done that for my custom view class and adapted my code to your case. I didn't run it because I don't have your code, but the main idea should be understandable:

You should override save and restore procedures for StyleAdaptation, so they store state separately for each instance, because they have different ids. The same ids will have their children, so you need to remember childs state manually.

Add these lines into StyleAdaptation class:

protected static class SavedState extends BaseSavedState {

    private final int style;

    public SavedState(Parcelable superState, int style) {
        super(superState);
        this.style = style;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        super.writeToParcel(out, flags);
        out.writeInt(style);
    }

    @Override
    public String toString() {
        String str = "MyCardView.SavedState{"
                + Integer.toHexString(System.identityHashCode(this))
                + " style=" + style;
        return str + "}";
    }

    private SavedState(Parcel in) {
        super(in);
        style = in.readInt();
    }

    public int getStyle() {
        return style;
    }

    public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {

        public SavedState createFromParcel(Parcel in) {
            return new SavedState(in);
        }

        public SavedState[] newArray(int size) {
            return new SavedState[size];
        }

    };
}

@Override
public void onRestoreInstanceState(Parcelable state) {
    SavedState savedState = (SavedState) state;
    super.onRestoreInstanceState(savedState.getSuperState());
    style = savedState.getStyle();
    listener.onStyleChanged(style);
}

@Override
public Parcelable onSaveInstanceState() {
    Parcelable result = super.onSaveInstanceState();
    return new SavedState(result, style);
}

You can read more about saving a state of custom views in the following questions:

  1. How to prevent custom views from losing state across screen orientation changes
  2. Overriding View.onSaveInstanceState() and View.onRestoreInstanceState() using View.BaseSavedState?
Community
  • 1
  • 1
Artem Mostyaev
  • 3,874
  • 10
  • 53
  • 60