[英]Change text of TextView after inflating layout
I have a layout, default_label.xml
, like so: 我有一个布局
default_label.xml
,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Then, I have this class, which basically allows me to set the default button text for a spinner: 然后,有了这个类,基本上可以让我为微调器设置默认按钮文本:
public class NothingSelectedSpinnerAdapter implements SpinnerAdapter, ListAdapter {
protected static final int EXTRA = 1;
protected SpinnerAdapter adapter;
protected Context context;
protected int nothingSelectedLayout;
protected int nothingSelectedDropdownLayout;
protected LayoutInflater layoutInflater;
protected TextView label;
/**
* Use this constructor to have NO 'Select One...' item, instead use
* the standard prompt or nothing at all.
*
* @param spinnerAdapter wrapped Adapter.
* @param nothingSelectedLayout layout for nothing selected, perhaps
* you want text grayed out like a prompt...
* @param context Context
*/
public NothingSelectedSpinnerAdapter(
SpinnerAdapter spinnerAdapter,
int nothingSelectedLayout, Context context) {
this(spinnerAdapter, nothingSelectedLayout, -1, context);
}
/**
* Use this constructor to Define your 'Select One...' layout as the first
* row in the returned choices.
* If you do this, you probably don't want a prompt on your spinner or it'll
* have two 'Select' rows.
*
* @param spinnerAdapter wrapped Adapter. Should probably return false for isEnabled(0)
* @param nothingSelectedLayout layout for nothing selected, perhaps you want
* text grayed out like a prompt...
* @param nothingSelectedDropdownLayout layout for your 'Select an Item...' in
* the dropdown.
* @param context Context
*/
public NothingSelectedSpinnerAdapter(SpinnerAdapter spinnerAdapter,
int nothingSelectedLayout, int nothingSelectedDropdownLayout, Context context) {
this.adapter = spinnerAdapter;
this.context = context;
this.nothingSelectedLayout = nothingSelectedLayout;
this.nothingSelectedDropdownLayout = nothingSelectedDropdownLayout;
layoutInflater = LayoutInflater.from(context);
}
@Override
public final View getView(int position, View convertView, ViewGroup parent) {
// This provides the View for the Selected Item in the Spinner, not
// the dropdown (unless dropdownView is not set).
if (position == 0) {
return getNothingSelectedView(parent);
}
return adapter.getView(position - EXTRA, null, parent); // Could re-use
// the convertView if possible.
}
public int getPosition(String value) {
int index = 0;
for (int i = 1; i < getCount() + EXTRA; i++) {
if (getItem(i).equals(value)) {
index = i;
break;
}
}
return index;
}
public TextView getNothingSelectedView(ViewGroup parent) {
label = (TextView) layoutInflater.inflate(nothingSelectedLayout, parent, false);
return label;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
// Android BUG! http://code.google.com/p/android/issues/detail?id=17128 -
// Spinner does not support multiple view types
if (position == 0) {
return new View(context);
}
if (adapter.getItem(position-EXTRA).toString().equals("")){
View view = nothingSelectedDropdownLayout == -1 ?
new View(context) :
getNothingSelectedDropdownView(parent);
view.setEnabled(false);
view.setOnClickListener(null);
return view;
}
// Could re-use the convertView if possible, use setTag...
return adapter.getDropDownView(position - EXTRA, null, parent);
}
protected View getNothingSelectedDropdownView(ViewGroup parent) {
return layoutInflater.inflate(nothingSelectedDropdownLayout, parent, false);
}
@Override
public int getCount() {
int count = adapter.getCount();
return count == 0 ? 0 : count + EXTRA;
}
@Override
public Object getItem(int position) {
return position == 0 ? null : adapter.getItem(position - EXTRA);
}
@Override
public int getItemViewType(int position) {
return 0;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public long getItemId(int position) {
return position >= EXTRA ? adapter.getItemId(position - EXTRA) : position - EXTRA;
}
@Override
public boolean hasStableIds() {
return adapter.hasStableIds();
}
@Override
public boolean isEmpty() {
return adapter.isEmpty();
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
adapter.registerDataSetObserver(observer);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
adapter.unregisterDataSetObserver(observer);
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return position != 0; // Don't allow the 'nothing selected'
// item to be picked.
}
}
What I want to be able to do is change the text of the TextView
, something like: 我想要做的是更改
TextView
的文本,例如:
NothingSelectedSpinnerAdapter myAdapter = new NothingSelectedSpinnerAdapter(adapter, R.layout.default_label, getContext());
myAdapter.setText("Custom Label");
mySpinner.setAdapter(myAdapter);
However, when I try adding the following method to the above NothingSelectedSpinnerAdapter
class: 但是,当我尝试将以下方法添加到上述
NothingSelectedSpinnerAdapter
类中时:
public void setText(String text) {
label.setText(text);
}
I get the following error: 我收到以下错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“ void android.widget.TextView.setText(java.lang.CharSequence)”
What should I change? 我应该改变什么?
Take a look at the following three lines: 看一下以下三行:
NothingSelectedSpinnerAdapter myAdapter = new NothingSelectedSpinnerAdapter(adapter, R.layout.default_label, getContext());
The Adapter is instantiated, label is null
实例化适配器, 标签为
null
myAdapter.setText("Custom Label");
The TextView
label is still null
, that's why label.setText();
TextView
标签仍然为null
,这就是label.setText();
的原因label.setText();
causes a NullPointerException
导致
NullPointerException
mySpinner.setAdapter(myAdapter);
Now the runtime will be able to draw the Spinner
items. 现在,运行时将能够绘制
Spinner
项目。 This involves repeated calling of getView()
(at least once for every item which should be drawn). 这涉及到重复调用
getView()
(对于应该绘制的每个项目至少调用一次)。 After getView()
has been executed for position = 0
, you will have assigned a value to label . 在为
position = 0
执行getView()
之后,将为label分配一个值。 From now on, you can safely call setText()
on it. 从现在开始,您可以安全地对其调用
setText()
。
If you want to be able to call myAdapter.setText("Custom Label");
如果您希望能够调用
myAdapter.setText("Custom Label");
whenever you like without having to bother about the inner workings of the Adapter, then you can introduce a field private String mLabelText
and implement the method as follows 只要您不必担心适配器的内部工作原理,就可以引入字段
private String mLabelText
并实现以下方法
public void setText(String labelText){
mLabelText = labelText;
if (label != null){
label.setText(labelText);
}
}
One last step: don't forget to set the text right after initializing label 最后一步:别忘了在初始化标签后立即设置文本
public TextView getNothingSelectedView(ViewGroup parent) {
label = (TextView) layoutInflater.inflate(nothingSelectedLayout, parent, false);
label.setText(mLabelText);
return label;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.