简体   繁体   English

扩大布局后更改TextView的文本

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM