【问题标题】:Spinner doesn't look appropriate微调器看起来不合适
【发布时间】:2012-05-26 09:18:30
【问题描述】:

我的活动中有一个 Spinner。我使用 ArrayList 和自定义 SpinnerAdapter 来填充按下 Spinner 时弹出的列表。

我的问题是 Spinner 在未按下时在 Activity 上的外观。都是灰色的。没有文字可见。即使在我按下微调器然后从结果列表中选择一个项目后,微调器也不会填充文本。

另外,当我从 Spinner 中选择一个项目,然后打印所选项目的位置时,它会打印 -1。许多人评论说我的微调器没有附加数据列表,但显然有。我还能如何按下 Spinner 然后从结果列表中进行选择?

        // This sets up the adapter and the arraylist that contains the data
            private void setUpAdapter() {
                mData = new ArrayList<MyData>();
                mAdapter = new MyAdapter(mData);
                mSpinner.setAdapter(mAdapter);

                mSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
                    public void onItemSelected(AdapterView<?> parent,
                            View view, int pos, long id) {
                            MyData g = (MyData) parent.getItemAtPosition(pos);
                            // TODO
                        }

                        public void onNothingSelected(AdapterView parent) {
                          // Do nothing.
                        }
                });
            }


    // this populates the arraylist that is attached to the spinner's adapter
// it is called once an AsyncTask finishes pulling data from a local database
            private void populateSpinner(ArrayList<MyData> result) {
                if (result != null) {
                    if (mData == null) {
                        mData = new ArrayList<MyData>();
                    }
                    else {
                        mData.clear();
                    }

                    for (int index = 0; index < result.size(); index++) {
                        mData.add(result.get(index));
                    }

                    mSpinner.setSelected(0);
                }
            }




    // this is the adapter for the spinner
            private class MyAdapter implements SpinnerAdapter {

                ArrayList<MyData> data;

                public MyAdapter(ArrayList<MyData> data){
                    this.data = data;
                }

                @Override
                public int getCount() {
                    return data.size();
                }

                @Override
                public Object getItem(int position) {
                    return data.get(position);
                }

                @Override
                public long getItemId(int position) {
                    return position;
                }

                @Override
                public int getItemViewType(int position) {
                    return android.R.layout.simple_spinner_dropdown_item;
                }

                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    TextView v = new TextView(getApplicationContext());
                    v.setTextColor(Color.BLACK);
                    v.setText(data.get(position).getName());
                    v.setPadding(0, 20, 0, 20);
                    return v;
                }

                @Override
                public int getViewTypeCount() {
                    return 1;
                }

                @Override
                public boolean hasStableIds() {
                    return false;
                }

                @Override
                public boolean isEmpty() {
                    return false;
                }

                @Override
                public void registerDataSetObserver(DataSetObserver observer) {
                    // TODO Auto-generated method stub
                }

                @Override
                public void unregisterDataSetObserver(DataSetObserver observer) {
                    // TODO Auto-generated method stub
                }

                @Override
                public View getDropDownView(int position, View convertView, ViewGroup parent) {
                    return this.getView(position, convertView, parent);
                }
            }


<Spinner
    android:id="@+id/my_spinner"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />

【问题讨论】:

  • 尝试将 super.getView() 添加到您的 getView 覆盖
  • 如果可用,也将 super.onNothingSelected() 添加到您的适配器

标签: android spinner


【解决方案1】:
When I select an item from the Spinner and then print the selected item position, it prints -1

这是因为您引用的是 BLANK 列表

mData = new ArrayList<MyData>();
mAdapter = new MyAdapter(mData);
mSpinner.setAdapter(mAdapter);

在 AsynTask 的onPostExecute() 中设置微调器适配器。

@Override
protected void onPreExecute() {
        mData = new ArrayList<MyData>();
        super.onPreExecute();
}

@Override
protected Void doInBackground(String... params) {
        //gets "result" to fill mData
        return null;
}

@Override
protected void onPostExecute(Void result) {
    setUpAdapter();
}


private void setUpAdapter() {
    if (result != null) {
          if (mData == null) {
                 mData = new ArrayList<MyData>();
           }
           else {
                 mData.clear();
           }

           for (int index = 0; index < result.size(); index++) {
                 mData.add(result.get(index));
           }

            mAdapter = new MyAdapter(mData);
            mSpinner.setAdapter(mAdapter);
            mSpinner.setSelected(0);

            mSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
                public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
                        MyData g = (MyData) parent.getItemAtPosition(pos);
                        // TODO
                    }

                    public void onNothingSelected(AdapterView parent) {
                      // Do nothing.
                    }
            });
        }

【讨论】:

  • 我不确定我是如何引用空列表的。显然,微调器正在填充项目。还是我误解了你的意思?我在许多其他地方使用 ListView 执行此操作。我将一个空的(但已实例化的)ArrayList 扔到 Adapter 中,然后当我得到它时将数据复制到 Adapter 中。
  • 我将 setAdapter 调用移至 AsyncTask 的后执行,但行为没有变化。
  • null 我的意思是空白(已初始化但没有数据),就像我向您展示的那样实现。
  • 是的,我最初初始化Adapter的时候,ArrayList是空的。当 AsyncTask 完成从数据库中检索数据时,它被复制到 ArrayList 中。我认为这无关紧要,事实上,数据会显示在 Spinner 中。
  • 我还尝试简单地使用一个充满 MyData 对象的 ArrayAdapter(我在 MyData 中创建了一个 toString 方法,以便 Spinner 知道要显示什么)。同样,数据显示在微调器中,但是当我选择某些东西时,微调器上没有文本,getSelectedItemPosition 返回 -1。
【解决方案2】:

为您的微调器使用 Activity 上下文而不是 Application 上下文。请参阅getApplicationContext() api 的文档以了解其正确用法。

将活动上下文传递给MyAdapter,并在getView回调中使用它来创建TextView

mAdapter = new MyAdapter(mData, this); // this is activity context.

在我的适配器中:

public MyAdapter(ArrayList<MyData> data, Context context){
     this.data = data;
     mContext = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
     TextView v = new TextView(mContext);
     v.setTextColor(Color.BLACK);
     v.setBackgroundColor(Color.WHITE);
     v.setText(data.get(position).getName());
     v.setPadding(0, 20, 0, 20);
     return v;
}

【讨论】:

  • 我同意这是一个错误,我已经纠正了它,但我的问题仍然存在。选择一个项目并调用 getSelectedItemPosition 后,Spinner 上没有显示任何文本仍然返回 -1。
【解决方案3】:

您可以使用 xml 属性 android:layout_height 设置静态大小。 建议使用 dp 单位而不是 px 以实现多屏兼容性。

至于文本,请尝试在 Spinner xml 中使用android:prompt 属性。对于颜色我猜它就像其他小部件一样,只需使用android:textColor

【讨论】:

  • 正如 amp 所说,Spinner 没有 textColor 属性。我不确定为什么没有文本可见,但它为文本腾出空间,因为高度尺寸会根据选择的字符串而变化。另外,我知道我可以使用 layout_height 属性设置静态高度,但我希望像单行属性这样的东西。
  • @amp 你是对的......不幸的是,设置微调器文本颜色似乎比看起来更复杂。看到这个:stackoverflow.com/questions/6159113/…
  • 关于身高问题,我认为没有其他解决方案。也许你可以实现 Spinner 类,但如果你没有一个很好的理由来固定高度(除了看起来很好的布局),我认为这是不可行的。当然这取决于你。
  • @Andrew 也许问题是&lt;spinner&gt; 属性...请添加此小部件的代码 xml。
  • 完成。没什么大不了的。我确实为 Spinner 指定了一个确切的高度。我只是不明白为什么没有显示文字。
【解决方案4】:

此代码正在运行,微调器正确显示该字段,但我必须说它可能不是 100% 完美,由于某种原因我无法将字段的初始值留空,默认情况下它的值为项目 0。 包 com.cccheck;

public class OneCheckActivity extends Activity {

LayoutInflater factory;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.spinner_view);
    ArrayList tdata = new ArrayList<MyData>();
    MyData mdata =new MyData();
    mdata.setName("");
    mdata.setData("-1");
    MyData ndata =new MyData();
    ndata.setName("ciao belluzzo");
    ndata.setData("1");
    tdata.add(mdata);
    tdata.add(ndata);
    mdata= new MyData();
    mdata.setName("vai alla fnac");
    mdata.setData("2");
    tdata.add(mdata);
    mSpinner = (Spinner) findViewById(R.id.my_spinner);
    factory = LayoutInflater.from(this);

    populateSpinner(tdata);

    setUpAdapter();
    mSpinner.setSelected(false);
    try  {
        mAdapter.notify();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    //mAdapter.registerDataSetObserver(new MyObserver());
}
ArrayList<MyData> mData;
MyAdapter mAdapter = new MyAdapter(null);
Spinner mSpinner;
// This sets up the adapter and the arraylist that contains the data
private void setUpAdapter() {
    mSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> parent,
                View view, int pos, long id) {
                MyData g = (MyData) parent.getItemAtPosition(pos);
                // TODO
                Toast.makeText(OneCheckActivity.this , "selected item : " + pos + ", value: " + g.getData(),Toast.LENGTH_LONG).show();

            }
        @Override
            public void onNothingSelected(AdapterView parent) {
              // Do nothing.
            }

    });
}


  // this populates the arraylist that is attached to the spinner's adapter
  //it is called once an AsyncTask finishes pulling data from a local database
private void populateSpinner(ArrayList<MyData> result) {
    if (result != null) {
        if (mData == null) {
            mData = new ArrayList<MyData>();
        }
        else {
            mData.clear();
        }

        for (int index = 0; index < result.size(); index++) {
            mData.add(result.get(index));
        }
        mAdapter = new MyAdapter(mData);

        mSpinner.setAdapter(mAdapter);
    }
}




// this is the adapter for the spinner
private class MyAdapter implements SpinnerAdapter {

    ArrayList<MyData> data;

    public MyAdapter(ArrayList<MyData> data){
        this.data = data;
    }
    public void updateData(ArrayList<MyData> data){
        this.data = data;
    }

    @Override
    public int getCount() {
        return data.size(); 
        }

    @Override
    public Object getItem(int position) {
        return data.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        return android.R.layout.simple_spinner_dropdown_item;
    }

    @Override
    public LinearLayout getView(int position, View convertView, ViewGroup parent) {
        LinearLayout pv = (LinearLayout)(factory.inflate(R.layout.spinner_item, null));
        TextView tv = (TextView) pv.findViewById(R.id.textviewid);
        tv.setTextColor(Color.BLACK);
        MyData item = data.get(position);
        tv.setText( item.getName() + " - " + item.getData() + " ");
        tv.setPadding(0, 20, 0, 20);
        return pv;
    }

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public boolean isEmpty() {
        return data.isEmpty();
    }

    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        // TODO Auto-generated method stub

    }

    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {
        // TODO Auto-generated method stub
    }

    @Override
    public LinearLayout getDropDownView(int position, View convertView, ViewGroup parent) {
        if (convertView instanceof LinearLayout) System.out.println("%%%%%%%%%%%%%%55555 hai ragione");
        return this.getView(position, convertView, parent);
    }
}




}

将其用作 spinner_item.xml 的布局

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>

<TextView 
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="28px"
android:id="@+id/textviewid"
/>

</LinearLayout>

【讨论】:

  • 这和hotveryspicy的实现很相似,并没有解决我的问题。
  • 如果你越过你的鼻子,你会发现我如此耐心地发布的代码确实解决了你的问题,但你太自大了,无法接受它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
相关资源
最近更新 更多