I am trying to reference a sibling control through XML.
To declare an attribute to reference an id from MyTextView:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyTextView">
<attr name="valueTextViewId" format="reference" />
</declare-styleable>
</resources>
fragment_example.xml - How to use custom attribute:
<!-- 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 - Inflating the controls
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// calls MyTextView Ctor
View v = inflater.inflate(R.layout.fragment_example, container, false);
}
MyTextView class constructor - During inflation do something with referenced 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
}
}
}
in this example v
is always null
. I assume because during Layout Inflation, the controls are not added yet. Another thing to note is that this is in a Fragment
, therefore that might be the reason I cant find the view in the parent activity.
Is it possible to reference a control from another like this?
One significant monetary way to curb Inflation is to control the money supply in the economy. If the money supply goes down, the demand for goods will reduce, causing a price fall. Another way to curb the money supply is when the government withdraws specific paper notes or coins from circulation.
A general increase in prices in an economy and consequent fall in the purchasing value of money. See also core inflation; hyperinflation; stagflation.
There are four basic strategies that central banks have used to control and reduce inflation: exchange-rate pegging; monetary targeting; inflation targeting; and.
The Fed's No. 1 mandate is to control inflation, and the most influential player in the fight against inflation is the Federal Reserve chair. Their most powerful tool is to raise interest rates.
Is it possible to reference a control from another like this?
It is possible to reference another View
from a View
.
But to do property checking in the constructor of a View
is not advised.
There is no guarantee that any particular View
is instantiated before any other during View inflation.
Compare these two layouts: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" />
In this example, it's clear that property checking from the constructor will not work in one of these layouts.
I agree that it is possible to store the reference to another View
within a 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);
}
But you should definitely do any and all property checking within the Activity
or 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
//
}
if a textview with the id of bar is available within the id of bar, you can do something like this.
<com.example.MyTextView
android:id="@+id/foo"
...
android:tag="bar" />
<com.example.MyTextView android:id="@+id/bar" />
and
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
}
i would just pass the id as a tag on your MyTextView so you dont need to create a new attribute.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With