在通货膨胀期间如何引用另一个控件?

Tom*_*ear 6 android android-custom-view attr android-layout android-view

我试图通过XML引用兄弟控件.

声明一个属性以引用MyTextView中的id:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyTextView">
        <attr name="valueTextViewId" format="reference" />
    </declare-styleable>
</resources>
Run Code Online (Sandbox Code Playgroud)

fragment_example.xml - 如何使用自定义属性:

<!-- Declare a "Title" text view that references a "Value" -->
<com.example.MyTextView
    android:id="@+id/foo"
    example:valueTextViewId="@id/bar"
    ... />

<!-- Depending on the "text" attribute of this "Value" textview -->
<!-- Do something within "Title" textview -->
<com.example.MyTextView android:id="@+id/bar" />
Run Code Online (Sandbox Code Playgroud)

MyFragment.java - 膨胀控件

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) {
        // calls MyTextView Ctor
    View v = inflater.inflate(R.layout.fragment_example, container, false);
}
Run Code Online (Sandbox Code Playgroud)

MyTextView类构造函数 - 在通胀期间使用引用的textview做一些事情:

public TextView(Context context, AttributeSet attrs) {
    super(context, attrs);

    TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.MyTextView);
    int refId = a.getResourceId(R.styleable.MyTextView_valueTextViewId);

    // Updated to use context
    if (refId > -1 && context instanceof Activity) {
        Activity a = (Activity)context;
        View v = a.findViewById(refId);

        // THE PROBLEM: v is null
        if (v != null) {
            // In my case, I want to check if the "Value" textview
            // is empty. If so I will set "this" textColor to gray
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在这个例子v中总是如此null.我假设因为在布局通胀期间,控件尚未添加.另一件需要注意的是,这是因为这Fragment可能是我无法在父活动中找到视图的原因.

是否有可能像这样引用另一个控件?

Eri*_*wer 2

是否可以像这样引用另一个控件?

可以View从 a引用另一个View

但不建议在a 的构造函数中进行属性检查。 无法保证在视图膨胀期间任何特定项都会先于其他任何特定项实例化。 View
View

比较这两种布局:
first_layout.xml

<com.example.MyTextView
    ...
    android:id="@+id/foo"
    example:valueTextViewId="@+id/bar" />

<com.example.MyTextView
    ...
    android:id="@+id/bar" />
Run Code Online (Sandbox Code Playgroud)

second_layout.xml

<com.example.MyTextView
    ...
    android:id="@+id/bar" />

<com.example.MyTextView
    ...
    android:id="@+id/foo"
    example:valueTextViewId="@+id/bar" />
Run Code Online (Sandbox Code Playgroud)

在此示例中,很明显,构造函数的属性检查在这些布局之一中不起作用。

我同意可以将对另一个的引用存储ViewView

public MyTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyTextView);
    mReferenceId = a.getResourceId(R.styleable.MyTextView_valueTextViewId);
    ...
}

private int mReferenceId;

public View getReferenceViewFromActivity() {
    if (getContext() instanceof Activity) {
        return ((Activity)getContext()).findViewById(mReferenceId);
    return null;
}

public View getReferenceView(View view) {
    return view.findViewById(mReferenceId);
}
Run Code Online (Sandbox Code Playgroud)

Activity但您绝对应该在或内进行所有属性检查Fragment

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    MyTextView myTextView = (MyTextView)view.findViewById(R.id.foo);
    MyReferenceView refView = (MyReferenceView)myTextView.getReferenceView(view);
    //
    // do property checking
    //
}
Run Code Online (Sandbox Code Playgroud)