安卓:一个ListView内纱厂失去它们的值当我添加动态新的ListView项 [英] Android: Spinners within a ListView loose their values when I add dynamically new ListView entries

查看:165
本文介绍了安卓:一个ListView内纱厂失去它们的值当我添加动态新的ListView项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的活动包含一个按钮和一个ListView。 ListView控件包含一个微调和一个EditText视图。我用的按钮,每次我想插入我的活动的ListView中一个新的行条目。

我按照这样一个在这里previous计算器线程的指令:<一href="http://stackoverflow.com/questions/3952375/android-listview-with-spinner-and-a-checkbox">Android列表视图以微调和复选框,了解如何填充列表视图中包含纱厂可获得焦点对象。

我的问题是,在previous的ListView项的微调值丢失(实际工作的微调将返回到默认设置)每次我动态地添加在ListView新的ListView项。假设为简单起见,我的纱厂都填充了以下数据:

 字符串spinner_data [] = {苹果,香蕉,梨花,西瓜,草莓};
 

例如,如果我选择我的第一个ListView的微调值是梨,然后我添加一个新的ListView条目我的按钮,梨条目从第一ListView的微调,默认值为苹果消失出现)。

任何帮助是AP preciated!

这是我的活动:

  @覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);

    LV =(ListView控件)findViewById(R.id.lv);
    DA =新的DataAdapter(这一点,新的ArrayList&LT; RAWDATA&GT;());
    lv.setAdapter(DA);

    btn_new =(按钮)findViewById(R.id.btn_new);

    btn_new.setOnClickListener(新View.OnClickListener(){

        @覆盖
        公共无效的onClick(视图v){
            // TODO自动生成方法存根
            da.add(新RAWDATA(本));
                      da.notifyDataSetChanged();
        }
    });

}
 

该RAWDATA类是这个:

 公共类RAWDATA {
私人诠释selected_position;
私人ArrayAdapter&LT; CharSequence的&GT;适配器;

公共RAWDATA(上下文的背景下)
{
    适配器= ArrayAdapter.createFromResource(背景下,R.array.data,android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}

公共ArrayAdapter&LT; CharSequence的&GT; getAdapter()
{
    返回适配器;
}

/ **
 *获取适配器的项目,从选定位置的文本
 * @返回
 * /
公共字符串的getText()
{
    回报(字符串)adapter.getItem(selected_position);
}

公众诠释getSelected()
{
    返回selected_position;
}

公共无效的setSelected(INT选择)
{
    this.selected_position =选择;
}
 }
 

该DataArrayAdapter如下:

 公共类DataArrayAdapter扩展ArrayAdapter&LT; RAWDATA&GT; {
私人活动myContext;
//私人最终名单,其中,RAWDATA&GT;清单;

公共DataArrayAdapter(活动背景下,列表与LT; RAWDATA&GT;名单)
{
    超(背景下,R.layout.row_view,清单);
    myContext =背景;
}

静态类ViewHolder
{
    保护RAWDATA数据;
    保护微调SPN;
    受保护的EditText EDT;
}

@覆盖
公共查看getView(INT位置,查看convertView,父母的ViewGroup)
{
    查看查看= NULL;
    如果(convertView == NULL)
    {
        LayoutInflater充气= myContext.getLayoutInflater();
        鉴于= inflator.inflate(R.layout.row_view,NULL);

        最后ViewHolder viewHolder =新ViewHolder();

        viewHolder.edt =(EditText上)view.findViewById(R.id.edt);
        viewHolder.data =新RAWDATA(myContext);
        viewHolder.spn =(微调)view.findViewById(R.id.spn);
        viewHolder.spn.setAdapter(viewHolder.data.getAdapter());

    viewHolder.spn.setOnItemSelectedListener(新OnItemSelectedListener(){

        @覆盖
        公共无效onItemSelected(适配器视图&LT;&GT;为arg0,查看ARG1,
                    INT arg2_position,长ARG3){
                // TODO自动生成方法存根
    viewHolder.data.setSelected(arg2_position);
            }

            @覆盖
            公共无效onNothingSelected(适配器视图&LT;&GT;为arg0){
                // TODO自动生成方法存根

            }
        });

        //更新的TextView,以反映什么在微调
        view.setTag(viewHolder);
    }
    其他
    {
        鉴于= convertView;
    }

    //这是被调用每次在ListView刷新
    ViewHolder支架=(ViewHolder)view.getTag();

               holder.spn.setSelection(的getItem(位置).getSelected());

    返回查看;
}

 }
 

解决方案

你不处理的情况时, getView 得到一个非空 convertView 。在你的榜样,后添加一个项目,的ListView 刷新本身,而应该显示梨的位置获得一个现有的 convertView ,你只要把它传递沿的ListView 没有设定数据的当前位置(即使用previously显示苹果的)。你可以不依赖于的ListView 项存储任何数据,你应该总是设置位置正确的内容在 getView 的方法你适配器。 只是要清楚,我看你的code将所选的位置 getView 的结束,但问题是,无论被标记为您的convertView当它传递以 getView 通过回收机制的ListView 是随机的,可以用它在使用之前显示的任何位置相关联。

为了使应用程序的工作,你必须创建selectedItem属性值的数组,你所有的纺纱厂,并把它附加一个成员适配器。你必须更新每个OnItemSelected事件的对应值,你会为每一个添加按钮,然后单击添加一个新的价值。而当你prepare您在 getView 查看你刚才设置的选择纺纱指数在您的阵列对应的值。

My activity contains a button and a ListView. The ListView contains a Spinner and an EditText view. I use the button each time I want to insert a new row entry in my Activity's ListView.

I have followed the instructions of previous stackoverflow threads like this one here: Android Listview with spinner and a checkbox on how to populate ListViews with focusable objects like Spinners.

My problem is that each time I dynamically add a new ListView entry in the ListView, the Spinner value of the previous ListView entry is lost (actuall the Spinner returns to its default setting). Say for simplicity that my Spinners are populated with the following data:

 String spinner_data[] = {"apple", "banana", "pear", "watermelon", "strawberry"};

For example, if I select my first ListView's Spinner value to be "pear" and then I add a new ListView entry with my Button, the "pear" entry disappears from the 1st ListView Spinner and the default value "apple" appears).

Any help is appreciated!

This is my activity:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    lv = (ListView) findViewById(R.id.lv);       
    da = new DataAdapter(this, new ArrayList<RawData>());
    lv.setAdapter(da);

    btn_new = (Button)findViewById(R.id.btn_new);

    btn_new.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            da.add(new RawData(this));
                      da.notifyDataSetChanged();
        }
    });

}

The RawData class is this one:

 public class RawData {
private int selected_position;
private ArrayAdapter<CharSequence> adapter;

public RawData(Context context)
{
    adapter = ArrayAdapter.createFromResource(context, R.array.data, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}

public ArrayAdapter<CharSequence> getAdapter() 
{         
    return adapter;     
}

/**
 * get adapter's item text from selected position
 * @return
 */
public String getText() 
{         
    return (String) adapter.getItem(selected_position);     
}

public int getSelected() 
{   
    return selected_position;     
}

public void setSelected(int selected) 
{         
    this.selected_position = selected;     
}
 }

The DataArrayAdapter is the following:

 public class DataArrayAdapter extends ArrayAdapter<RawData> {
private Activity myContext;
//private final List<RawData> list;

public DataArrayAdapter(Activity context, List<RawData> list) 
{         
    super(context, R.layout.row_view, list);         
    myContext = context;
} 

static class ViewHolder
{
    protected RawData data;
    protected Spinner spn;
    protected EditText edt;
}

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    View view = null;
    if ( convertView == null )
    {
        LayoutInflater inflator = myContext.getLayoutInflater();             
        view = inflator.inflate(R.layout.row_view, null);

        final ViewHolder viewHolder = new ViewHolder(); 

        viewHolder.edt = (EditText)view.findViewById(R.id.edt);
        viewHolder.data = new RawData(myContext);
        viewHolder.spn = (Spinner)view.findViewById(R.id.spn);
        viewHolder.spn.setAdapter(viewHolder.data.getAdapter());

    viewHolder.spn.setOnItemSelectedListener(new OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> arg0, View arg1,
                    int arg2_position, long arg3) {
                // TODO Auto-generated method stub
    viewHolder.data.setSelected(arg2_position);
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub

            }
        });

        // Update the TextView to reflect what's in the Spinner
        view.setTag(viewHolder);
    }
    else
    {
        view = convertView;
    }

    // This is what gets called every time the ListView refreshes
    ViewHolder holder = (ViewHolder) view.getTag();

               holder.spn.setSelection(getItem(position).getSelected());

    return view;
}

 }

解决方案

You're not handling the situation when getView gets a non-null convertView. In your example, after you add an item, ListView refreshes itself, and position that should display 'pear' gets an existing convertView (the one that was used previously to display 'apple') and you just pass it along to ListView without setting the data for current position. You cannot rely on ListView items to store any data, you should always set correct contents for position in getView method of your adapter. Just to be clear, I see that your code sets the selected position in the end of getView but the issue is that whatever is tagged to your convertView when it is passed to getView by recycler mechanism in ListView is random and can be associated with any position it used to display before.

To make your application work you'll have to create array of selectedItem values for all your spinners, and attach it as a member to your adapter. You'll have to update the corresponding value on each OnItemSelected event and you'll add a new value for each "add" button click. And when you prepare your view in getView you'll just set the selected spinners index to corresponding value in your array.

这篇关于安卓:一个ListView内纱厂失去它们的值当我添加动态新的ListView项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆