如何在片段自定义视图中设置唯一ID

时间:2016-05-07 14:17:37

标签: android android-layout android-fragments android-view

我有三个类,在拼写错误片段中我使用我的自定义类StyleAdaptation和SizeAndStyleAdaptation(和SizeAdaptation但忘了这一个)是同一个类(SizeAndStyle实现只是字体大小的微调器)并且它们扩展了一个CardView

在StyleAdaptation中,我有另一个自定义视图StyleAndColor,其中有四个用于粗体,斜体,下划线和最后一个用于颜色的按钮。

所以当我设置upper_style时我有一个问题,例如我设置为粗体,如果我更改片段并返回此处,则不保存该值。但是如果我在更改片段后更改ponc_style并返回,如果我设置为粗体,则两者(ponc_style和upper_style设置为粗体)问题来自id。

我不知道在这种情况下如何为childS分配一些独特的id。

当我调用其他类时,TypoFragment.java是我的根片段。

    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是一个类,我扩展了一个cardview,用于显示一些用于样式调整的字段

    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>

StyleAndColor.java扩展了RelativeLayout,其中我只有四个按钮用于粗体,斜体,下划线,最后一个用于设置文本颜色。

    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);
    }
}

并且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>

错字片段的截图:

typo fragment screenshot

1 个答案:

答案 0 :(得分:0)

您可以手动保存和恢复状态StyleAdaptation

我已经为我的自定义视图类完成了这项工作,并根据您的情况调整了我的代码。我没有运行它,因为我没有你的代码,但主要的想法应该是可以理解的:

  

您应该覆盖StyleAdaptation的保存和恢复过程,所以   它们为每个实例分别存储状态,因为它们具有不同的ID。相同的ID会有他们的孩子,所以你需要手动记住孩子的状态。

将这些行添加到StyleAdaptation类:

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);
}

您可以在以下问题中阅读有关保存自定义视图状态的更多信息:

  1. How to prevent custom views from losing state across screen orientation changes
  2. Overriding View.onSaveInstanceState() and View.onRestoreInstanceState() using View.BaseSavedState?