【问题标题】:Multiple instances of the same android compound component同一个android复合组件的多个实例
【发布时间】:2015-11-02 21:19:27
【问题描述】:

我有一个自定义的 EditText 组件(复合组件,基于 LinearLayout),我在同一个 Activity 中使用多个实例。 自定义组件按预期工作,但是,当我旋转 ui 时,在第二个组件中输入的文本突然被复制到第一个组件。否则,两个自定义组件的功能都完全符合预期。 这两个组件在活动布局中都有唯一的 id。

这是我的客户组件的代码:

public class MyEditText extends LinearLayout{
private EditText mEditText;
TextView mTextCounter;
private int errorIconRes;
private String textHint;
private boolean showLength;
private int maxCount;
private int lines;
private boolean phoneField;

private String errorMessage;

    public MyEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ZipEditText, 0, 0);

    phoneField = a.getBoolean(R.styleable.ZipEditText_phone, false);
    errorIconRes = a.getInt(R.styleable.ZipEditText_icon_err, R.drawable.form_error_icon);
    textHint = a.getString(R.styleable.ZipEditText_hint);
    maxCount = a.getInt(R.styleable.ZipEditText_maxLength, 100);
    lines = a.getInt(R.styleable.ZipEditText_lines, 1);
    showLength = a.getBoolean(R.styleable.ZipEditText_showLength, false);

    a.recycle();
   LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = inflater.inflate(R.layout.comp_zip_edittext, this, true);
    mEditText = (EditText) v.findViewById(R.id.text_field);
    mEditText.addTextChangedListener(getTextWatcher());

    if (textHint!= null)mEditText.setHint(textHint);
    mImageViewError =  (ImageView) v.findViewById(R.id.icon_error);
    mTextCounter = (TextView) v.findViewById((R.id.text_counter));



    if (lines>1 && !phoneField) {
        mEditText.setLines(lines);
        mEditText.setSingleLine(false);
    }
    if (showLength) {
        mTextCounter.setVisibility(View.VISIBLE);
        mEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(maxCount)});
        mEditText.addTextChangedListener(getTextWatcherLength());
    } else {
        mTextCounter.setVisibility(View.GONE);
    }

这是我的自定义组件的布局文件:

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="center_horizontal"
        android:gravity="center_horizontal">

        <EditText
            android:id="@+id/text_field"
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            android:gravity="left"
            android:paddingLeft="10dp"
            android:singleLine="true"
            android:inputType="textNoSuggestions"
            android:layout_alignParentTop="true"
            />

        <ImageView
            android:id="@+id/icon_error"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:src="@drawable/form_error_icon"
            android:layout_marginTop="10dp"
            android:layout_marginRight="15dp"
            android:layout_alignRight="@id/text_field"
            android:layout_alignTop="@id/text_field"
            android:visibility="gone"/>
    </RelativeLayout>
    <TextView
        android:id="@+id/text_counter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="Small Text"
        android:layout_gravity="right"
        android:visibility="gone"/>
</LinearLayout>

这是我的活动布局文件:

   <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:zip="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_gravity="center_horizontal"
    android:gravity="center_horizontal"
    android:background="@color/white" >


    <TextView
        android:id="@+id/error_msg"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:gravity="center"
        android:textSize="18sp"
        android:textColor="@color/home_image_red"
        android:background="@color/zip_error_gray"
        android:text="Something went wrong"
        android:visibility="gone"
        />
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:layout_gravity="center_horizontal"
        android:gravity="center_horizontal"
        android:background="@color/white" >

        <TextView
            android:id="@+id/upsell"
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:textSize="18sp"
            android:text="Sign in to use all our features."
            />


        <com.myproject.android.components.MyEditText
            android:id="@+id/request_phone"
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            android:layout_marginTop="5dp"
            android:gravity="left"
            android:singleLine="true"
            zip:phone="true"
            zip:hint="@string/hint_phone"/>

        <com.myproject.android.components.MyEditText
            android:id="@+id/request_comments"
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            android:layout_marginTop="5dp"
            android:gravity="left"
            zip:lines="3"
            zip:maxLength="120"
            zip:showLength="true"
            zip:hint="@string/hint_comments"/>

        <CheckBox
            android:id="@+id/checkbox_request_visit"
            style="@style/contact_label"
            android:layout_centerInParent="true"
            android:text="@string/check_home_visit"
            android:checked="false" />

        <Button
            android:id="@+id/request_button"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:text="Request a Showing"
            android:textColor="@color/pbz_button_primary_foreground_color"
            android:textStyle="bold"
            android:background="@drawable/button_registration"
            android:gravity="center"/>

        <TextView
            android:id="@+id/terms_link"
            style="@style/FinePrint"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:gravity="center_horizontal"
            android:paddingBottom="5dp"
            android:text="@string/request_showing_terms"
            />
    </LinearLayout>
</LinearLayout>

【问题讨论】:

  • “两个组件在活动布局中都有唯一的 id”——是的,但是组件内的小部件没有。
  • 嗨 CommonsWare,我知道这一点。但是,我将如何给他们自定义 ID?这甚至可能吗?如果不是,是否意味着我不能在同一个活动中使用复合组件的多个实例?
  • “这可能吗?” -- 你可以打电话给他们setId()。在 Android 中有一些地方可以让系统为它们生成一个不同的视图 ID,但我不记得它在哪里。或者,在您的自定义 View 上实现 onSaveInstanceState()onRestoreInstanceState() 以自行管理状态唯一性。
  • 感谢 CommonsWare,我确实实现了 onSaveIsntacneState / onRestoreInstacneState 但这似乎不起作用。我会尝试按语法设置 id

标签: android custom-component


【解决方案1】:

我想出了如何做到这一点:不是通过 id 加载组件,而是解析树并按树中的位置加载它:

代替

mEditText = (EditText) v.findViewById(R.id.text_field);

这样做:

LinearLayout linearLayout = (LinearLayout) getChildAt(0);
mEditText = (EditText) relativeLayout.getChildAt(0);

这样,您可以避免在旋转后重新创建活动/片段时加载错误的组件

【讨论】:

    【解决方案2】:

    问题在于您的 EditText 组件的 Id 相同。尝试删除它的 id,并通过从 xml 扩展每个视图并将其添加到复杂布局中来分别创建自定义组件。

    【讨论】:

      猜你喜欢
      • 2018-11-21
      • 1970-01-01
      • 1970-01-01
      • 2011-12-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2022-10-26
      相关资源
      最近更新 更多