6

私はXMLを介して兄弟コントロールを参照しようとしています。 MyTextViewからIDを参照する属性を宣言するインフルエンザ中にコントロールを別のコントロールから参照する方法はありますか?

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="MyTextView"> 
     <attr name="valueTextViewId" format="reference" /> 
    </declare-styleable> 
</resources> 

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" /> 

MyFragment.java - 膨張させますコントロール

は常に nullである。この例では

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

: -

MyTextViewクラスのコンストラクタインフレ率の間には、参照先のTextViewで何かをします。私はレイアウトインフレの間、コントロールがまだ追加されていないと仮定します。注目すべきもう一つは、これはFragmentにあるということです。そのため、親アクティビティーでビューを見つけることができない可能性があります。

コントロールをこのような別のものから参照することはできますか?

答えて

2

このようなコントロールを参照することはできますか?

ViewViewから参照することは可能です。

コンストラクタのプロパティチェックを行うには、Viewのアドバイスはありません。
View inflationの間に特定のViewがインスタンス化されるという保証はありません。

は、これらの2つのレイアウトを比較します。この例では
first_layout.xml

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

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

second_layout.xml

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

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

、それはコンストラクタからチェックプロパティは、これらのレイアウトのいずれかで動作しないことは明らかです。

私はView内の別のViewへの参照を格納することが可能であることに同意:

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

しかし、あなたは間違いなくActivityFragment内のチェック任意およびすべてのプロパティを実行する必要があります。

@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 
    // 
} 
1

barのidを持つtextviewがbarのid内で使用できる場合は、このようなことができます。

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

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

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

     int barId = getResources().getIdentifier(getTag(), "id", packageName); 
     TextView bar = mActivity.findViewById(barId); 

    if (bar.getText() == "") { 
     // Gray out this "title" textview 
     setColor(android.R.color.gray); 
    } 

    // maybe set a text change listener to bar to make it future-proof 
} 

新しい属性を作成する必要がいけないので、私は自分のMyTextView上のタグとしてIDを渡します。

+0

これは面白くてスタートです。しかし、私は 'LayoutInflator'を使っているときに' mActivity'を渡すことはできません。 Ctorのコンテキスト属性がアクティビティ自体であるかどうかは私には分かりません。 –

+1

それは可能です。 'if(context instanceof Activity)'でチェックし、 '((Activity)context)'をキャストしてください – r2DoesInc

+0

おそらく、コンストラクタでそのロジックをしないでください。 'setActivityValue(mActivity)'のためにMyTextViewにメソッドを追加し、アクティビティが明示的に設定された後、他のテキストビューを隠すか操作するロジックを行います。 – r2DoesInc

1

コンストラクタ内の独自のプライベートフィールドに参照を保存します。あなたの場合、プライベートフィールドにrefIdを保存します。その後、onMeasure機能で使用してください。


参考ビューを取得する方法を使用しないことをお勧めします。 RelativeViewの子のlayout_toLeftOfなどの通常のケースを見ると、idは常にRelativeViewの子の1つで、したがって現在のビューの兄弟であることに気付くでしょう。その場合、getParent()を使用して親を取得し、ViewGroup(必ずしもそうではない)にキャストして、findViewByIdを使用して参照を含むビューを見つけることによって、ビューを取得するのは簡単です。この種類の制限(idは兄弟でなければなりません)を行うことができれば、おそらくこの依存関係をコンテキストから取り除くことができ、最終的にはビューが使用できなくなります。独自の属性を使用する代わりにsetBla()を使用してビューを設定する方がよいでしょう(このセッターが呼び出されなかった場合は、onMeasureでランタイムエラーが発生する可能性があります)。

1

私が知る限り、Activity'sのレイアウトは、 onCreateView()の方法で作成が完了したという保証はありません。

あなたは代わりに、このアプローチを試みることができる:

@Override 
public void onActivityCreated(Bundle savedInstanceState){ 
    mView.customMethodToSetTextColor(...) 
} 

onActivityCreated()を活動の作成が終了したときに呼び出され、FragmentlifecycleonCreateView()後にされています。

関連する問題