错行从微调定制列表视图中删除 [英] Wrong row deleted from custom listview with spinner

查看:268
本文介绍了错行从微调定制列表视图中删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作包含与删除按钮,我从主要活动更新自定义的ListView应用程序。

我从ListView中移除一行的问题,虽然我是从自定义列表视图中删除正确的索引并调用 notifyDataChanged()方法,GUI不正确更新。

下面我写了一个示例项目,就像在我的想法真正的只是更多的样本:


  • activity_main.xml中(主布局)包含的ListView只调用列表视图。

  • listview_row.xml包含两个纱厂(学生姓名和等级),设置和删除按钮和文本视图。

  • 学生类包含两个变量:名称(String)和等级(INT)

MainActivity.java:

 公共类MainActivity延伸活动{
    ListView控件的ListView;
    listviewAdapter适配器;
    ArrayList的<的Student GT;学生=新的ArrayList<>();    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);        的String []名=新的String [] {汤姆,奔,吉尔,亚当,摩西,阿迪,迈克尔,优思明,杰西卡,卡罗琳 阿维,耶尔};        students.add(新学生());
        students.add(新学生());
        students.add(新学生());        适配器=新listviewAdapter(这一点,学生,姓名);
        ListView控件=(ListView控件)findViewById(R.id.listView);
        listView.setAdapter(适配器);    }    公共无效updateStatus(INT位置)
    {
        查看convertView = listView.getChildAt(位置 - listView.getFirstVisiblePosition());
        TextView的tvValue =(TextView中)convertView.findViewById(R.id.tv_Value);
        微调spName =(微调)convertView.findViewById(R.id.spNames);
        微调spGrade =(微调)convertView.findViewById(R.id.spGrades);        tvValue.setText(。spName.getSelectedItem()的toString()+得到+ spGrade.getSelectedItem()的toString());
    }    @覆盖
    公共布尔onCreateOptionsMenu(菜单菜单){
        。getMenuInflater()膨胀(R.menu.menu_main,菜单);
        返回true;
    }    @覆盖
    公共布尔onOptionsItemSelected(菜单项项){
        INT ID = item.getItemId();
        如果(ID == R.id.action_Add)
        {
            students.add(新学生());
            adapter.notifyDataSetChanged();
            返回true;
        }
        返回super.onOptionsItemSelected(项目);
    }
}

listviewAdapter.java

 公共类listviewAdapter延伸BaseAdapter
{
    公共活动背景;
    公共LayoutInflater吹气;    私人的ArrayList<的Student GT;学生卡;
    私有String [] studentsNames;    公共listviewAdapter(Activity上下文,ArrayList的<的Student GT;学生的String []的名称)
    {
        超();
        studentID =学生;
        studentsNames =名称;        this.context =背景;
        this.inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }    @覆盖
    公众诠释的getCount(){
        返回studentID.size();
    }    @覆盖
    公共对象的getItem(INT位置){
        返回studentID.get(位置);
    }    @覆盖
    众长getItemId(INT位置){
        返回的位置;
    }
    @覆盖
    公众诠释getViewTypeCount(){
        返回studentID.size()+ 1;
    }    @覆盖
    公众诠释getItemViewType(INT位置){
        返回的位置;
    }    公共类ViewHolder {
        微调spNames,spGrades;
        TextView的tvValue;
        按钮btnSet,btnRemove;
    }    @覆盖
    公共查看getView(INT I,观景,最终的ViewGroup的ViewGroup)
    {
        最后ViewHolder持有人;
        如果(查看== NULL){
            持有人=新ViewHolder();
            鉴于= inflater.inflate(R.layout.listview_row,NULL);            holder.spNames =(微调)view.findViewById(R.id.spNames);
            holder.spGrades =(微调)view.findViewById(R.id.spGrades);
            holder.tvValue =(TextView中)view.findViewById(R.id.tv_Value);
            holder.btnSet =(按钮)view.findViewById(R.id.btn_setValue);
            holder.btnRemove =(按钮)view.findViewById(R.id.btn_Remove);
            view.setTag(保持器);
            holder.spNames.setTag(0);
            holder.spGrades.setTag(0);
        }
        其他{
            支架=(ViewHolder)view.getTag();
        }        //弹出微调名
        ArrayAdapter<串GT; studentsNamesAdapater =新ArrayAdapter<>
                (view.getContext(),android.R.layout.simple_spinner_dropdown_item,studentsNames);
        studentsNamesAdapater.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        holder.spNames.setAdapter(studentsNamesAdapater);        //弹出微调等级
        的String [] =等级新的String [101];
        对于(INT级= 0;&级LT; 101;等级++)
            等级[等级] =将String.valueOf(级);        最后ArrayAdapter<串GT; studentsGradesAdapter =新ArrayAdapter<>
                (view.getContext(),android.R.layout.simple_spinner_dropdown_item,成绩);
        studentsGradesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        holder.spGrades.setAdapter(studentsGradesAdapter);
        //选择正确的spNames指数
        holder.spNames.setSelection((整数)holder.spNames.getTag());
        //保存微调指数
        holder.spNames.setOnItemSelectedListener(新AdapterView.OnItemSelectedListener(){
            @覆盖
            公共无效onItemSelected(适配器视图<>母公司,观景,INT位置,长的id){
                holder.spNames.setTag(位置);
            }            @覆盖
            公共无效onNothingSelected(适配器视图<>母公司){            }
        });        //选择正确的spGrades指数
        holder.spGrades.setSelection((整数)holder.spGrades.getTag());
        //保存微调指数
        holder.spGrades.setOnItemSelectedListener(新AdapterView.OnItemSelectedListener(){
            @覆盖
            公共无效onItemSelected(适配器视图<>母公司,观景,INT位置,长的id){
                holder.spGrades.setTag(位置);
            }            @覆盖
            公共无效onNothingSelected(适配器视图<>母公司){            }
        });        //集(变量的TextView)
        holder.btnSet.setTag(ⅰ);
        holder.btnSet.setOnClickListener(新View.OnClickListener(){
            @覆盖
            公共无效的onClick(视图v){
                //更新studentID
                INT位置=(整数)v.getTag();
                学生TMP =新的学生(。holder.spNames.getSelectedItem()的toString(),Integer.valueOf(holder.spGrades.getSelectedItem()的toString()));
                studentID.set(位置,TMP);
                ((MainActivity)上下文).updateStatus(位置);
            }
        });
        //删除一行
        holder.btnRemove.setTag(ⅰ);
        holder.btnRemove.setOnClickListener(新View.OnClickListener(){
            @覆盖
            公共无效的onClick(视图v){
                INT位置=(整数)v.getTag();
                studentID.remove(位置);
                // notifyDataSetChanged();
                ((MainActivity)上下文).adapter.notifyDataSetChanged();                //调试
                字符串dStatus =矢量大小:+ stu​​dentID.size()+\\ n;
                对于(INT指数= 0;指数 - LT; studentID.size();指数++)
                    dStatus + = studentID.get(指数)。名称++ stu​​dentID.get(指数).grade +\\ n;
                Toast.makeText(v.getContext(),dStatus,Toast.LENGTH_SHORT).show();
            }
        });        返回视图。
    }
}

我的问题是,GUI不正确地更新,在GUI上删除的项目仍然出现在屏幕上,你可以看到如下:

在这里输入的形象描述

有人可以指导我请了如何从GUI也拆下右行?

修改


  1. 我为你回答我,我的更新列表视图适配器和使用标签无法正常工作。

  2. 我还发现,当我尝试添加到学生删除一个后奇怪的问题。出于某种原因,它记住最后的学生,具有完整的数据回报他,因为你可以在更新画面看到的。

EDIT2

在万一有人想尝试一下,我添加了Student类和XML来源:

Student.java

 公共类学生
{
    公共字符串名称;
    公众诠释品位;    公共学生()
    {
        NAME =;
        级= 0;
    }    公益助学(字符串_name,诠释_grade)
    {
        名称= _name;
        等级= _grade;
    }
}

activity_main.xml中

 < LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s
    机器人:方向=垂直
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    工具:上下文=MainActivity。>    < ListView控件
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =FILL_PARENT
        机器人:ID =@ + ID /的ListView
        机器人:layout_gravity =CENTER_HORIZONTAL
        机器人:dividerHeight =2DP/>
< / LinearLayout中>

listview_row.xml

 <?XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:方向=垂直的android:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:背景=#c4e0ff>    <的LinearLayout
        机器人:方向=横向
        机器人:layout_width =match_parent
        机器人:layout_height =WRAP_CONTENT>        <微调
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =WRAP_CONTENT
            机器人:ID =@ + ID / spNames/>        <微调
            机器人:layout_width =100dp
            机器人:layout_height =WRAP_CONTENT
            机器人:ID =@ + ID / spGrades
            机器人:layout_marginLeft =10dp/>        <按钮
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =WRAP_CONTENT
            机器人:文字=设置值
            机器人:ID =@ + ID / btn_setValue/>
    < / LinearLayout中>    <的LinearLayout
        机器人:方向=横向
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent>        <的TextView
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =WRAP_CONTENT
            机器人:textAppearance =机器人:ATTR / textAppearanceMedium
            机器人:文字=中文字
            机器人:ID =@ + ID / tv_Value/>        <按钮
            风格=机器人:ATTR / buttonStyleSmall
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =WRAP_CONTENT
            机器人:文字=删除
            机器人:ID =@ + ID / btn_Remove
            机器人:layout_marginLeft =30dp/>    < / LinearLayout中>< / LinearLayout中>


解决方案

问题是与

  holder.spNames.setTag(位置);

  holder.spNames.setSelection((整数)holder.spNames.getTag());

当你在设置标签的名称为onItemSelected()。当你删除的项目从学生的名单中删除的项目,但什么标签

让我们假设你在0删除的项目。

现在,当notifyDataSetChanged()之称,将重新填充根据数据列表视图是可用的。现在,这里

 其他{
        支架=(ViewHolder)view.getTag();
    }

获取调用。
当getView第i = 0(),您将得到previous填充的列表中的第0指标的看法。因此,(整数)holder.spNames.getTag()将指向previous标签(即previous名单0)。这可能是问题的原因。

我张贴的更新code

listviewAdapter

 公共类ListviewAdapter延伸BaseAdapter
{
公共活动背景;
公共LayoutInflater吹气;
私人的ArrayList<的Student GT;学生卡;
私有String [] studentsNames;
私人请将isDeleted boolean值;
公共ListviewAdapter(Activity上下文,ArrayList的<的Student GT;学生的String []的名称)
{
    超();
    studentID =学生;
    studentsNames =名称;    this.context =背景;
    this.inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}@覆盖
公众诠释的getCount(){
    返回studentID.size();
}@覆盖
公益助学的getItem(INT位置){
    返回studentID.get(位置);
}@覆盖
众长getItemId(INT位置){
    返回的位置;
}
公共类ViewHolder {
    微调spNames,spGrades;
    TextView的tvValue;
    按钮btnSet,btnRemove;
    INT指数;
}@覆盖
公共查看getView(INT I,观景,最终的ViewGroup的ViewGroup)
{
    最后ViewHolder持有人;
    如果(查看== NULL){
        持有人=新ViewHolder();
        鉴于= inflater.inflate(R.layout.listview_row,NULL);        holder.spNames =(微调)view.findViewById(R.id.spNames);
        holder.spGrades =(微调)view.findViewById(R.id.spGrades);
        holder.tvValue =(TextView中)view.findViewById(R.id.tv_Value);
        holder.btnSet =(按钮)view.findViewById(R.id.btn_setValue);
        holder.btnRemove =(按钮)view.findViewById(R.id.btn_Remove);
        Log.e(IAM,被称为);
        view.setTag(保持器);
        //holder.spNames.setTag(0);
        //holder.spGrades.setTag(0);
    }
    其他{
        支架=(ViewHolder)view.getTag();
    }
    holder.index = I;
   如果(请将isDeleted){
       holder.tvValue.setText(的getItem(holder.index).getName()+得到+的getItem(holder.index).getGrade());
            }
    //弹出微调名
    ArrayAdapter<串GT; studentsNamesAdapater =新ArrayAdapter<串GT;
            (view.getContext(),android.R.layout.simple_spinner_dropdown_item,studentsNames);
    studentsNamesAdapater.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    holder.spNames.setAdapter(studentsNamesAdapater);    //弹出微调等级
    的String [] =等级新的String [101];
    对于(INT级= 0;&级LT; 101;等级++)
        等级[等级] =将String.valueOf(级);    最后ArrayAdapter<串GT; studentsGradesAdapter =新ArrayAdapter<串GT;
            (view.getContext(),android.R.layout.simple_spinner_dropdown_item,成绩);
    studentsGradesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    holder.spGrades.setAdapter(studentsGradesAdapter);
    //选择正确的spNames指数
    //holder.spNames.setSelection((Integer)holder.spNames.getTag());
    holder.spNames.setSelection(的getItem(holder.index).getNameIndex());
    //保存微调指数
    holder.spNames.setOnItemSelectedListener(新AdapterView.OnItemSelectedListener(){
        @覆盖
        公共无效onItemSelected(适配器视图<>母公司,观景,INT位置,长的id){
            //holder.spNames.setTag(position);
            的getItem(holder.index).setNameIndex(位置);
        }        @覆盖
        公共无效onNothingSelected(适配器视图<>母公司){        }
    });    //选择正确的spGrades指数
   // holder.spGrades.setSelection((整数)holder.spGrades.getTag());    holder.spGrades.setSelection(的getItem(holder.index).getGrageIndex());
    //保存微调指数
    holder.spGrades.setOnItemSelectedListener(新AdapterView.OnItemSelectedListener(){
        @覆盖
        公共无效onItemSelected(适配器视图<>母公司,观景,INT位置,长的id){
           // holder.spGrades.setTag(位置);
            的getItem(holder.index).setGrageIndex(位置);
        }        @覆盖
        公共无效onNothingSelected(适配器视图<>母公司){        }
    });    //集(变量的TextView)
    holder.btnSet.setTag(ⅰ);
    holder.btnSet.setOnClickListener(新View.OnClickListener(){
        @覆盖
        公共无效的onClick(视图v){
            //更新studentID
            //最终诠释位置= getRowPosition(V);
            INT位置=(整数)v.getTag();
           //学生TMP =新的学生(holder.spNames.getSelectedItem()的toString(),Integer.valueOf(holder.spGrades.getSelectedItem()的toString()));
           // studentID.set(位置,TMP);
            的getItem(位置).setName(holder.spNames.getSelectedItem()的toString());
            的getItem(位置).setGrade(Integer.valueOf(holder.spGrades.getSelectedItem()的toString()));
            holder.tvValue.setText(的getItem(位置).getName()+得到+的getItem(位置).getGrade());
            //((MainActivity)上下文).updateStatus(位置);
        }
    });
    //删除一行
    holder.btnRemove.setTag(ⅰ);
    holder.btnRemove.setOnClickListener(新View.OnClickListener(){
        @覆盖
        公共无效的onClick(视图v){
            //最终诠释位置= getRowPosition(V);
            INT位置=(整数)v.getTag();
            studentID.remove(位置);
            notifyDataSetChanged();
            //((MainActivity)上下文).adapter.notifyDataSetChanged();
            =请将isDeleted真实;
            //调试
            字符串dStatus =矢量大小:+ stu​​dentID.size()+\\ n;
            对于(INT指数= 0;指数 - LT; studentID.size();指数++)
                dStatus + = studentID.get(指数)。名称++ stu​​dentID.get(指数).grade +\\ n;
            Toast.makeText(v.getContext(),dStatus,Toast.LENGTH_SHORT).show();
        }
    });    返回视图。
}公共无效照片(){
    的for(int i = 0; I< studentID.size();我++){
        Log.e(姓名,+ stu​​dentID.get(ⅰ).getName());
        Log.e(级,+ stu​​dentID.get(ⅰ).getGrade());
    }
}
}

学生

 公共类学生{
公共字符串名称;
公众诠释品位;
私人诠释nameIndex;
私人诠释grageIndex;公共学生()
{
    NAME =;
    级= 0;
}公益助学(字符串_name,诠释_grade)
{
    名称= _name;
    等级= _grade;
}公共字符串的getName(){
    返回名称;
}公共无效setname可以(字符串名称){
    this.name =名称;
}公众诠释getGrade(){
    返回等级;
}公共无效setGrade(INT级){
    this.grade =等级;
}公众诠释getNameIndex(){
    返回nameIndex;
}公共无效setNameIndex(INT nameIndex){
    this.nameIndex = nameIndex;
}公众诠释getGrageIndex(){
    返回grageIndex;
}公共无效setGrageIndex(INT grageIndex){
    this.grageIndex = grageIndex;
}
}

I'm working on app that contains a custom ListView with a remove button that I update from the main activity.

I have an issue removing a row from the ListView, although I'm deleting the right index from the custom list view and call notifyDataChanged()method, GUI does not update correctly.

Here I wrote a sample project, like my real one in the idea just more sample:

  • activity_main.xml (main layout) contains ListView only called listview.
  • listview_row.xml contains two Spinners (student name and grade), set and remove button and text view.
  • Student class contains two variables: name (String) and grade (int)

MainActivity.java:

public class MainActivity extends Activity {
    ListView listView;
    listviewAdapter adapter;
    ArrayList<Student> students = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String[] names = new String[]{"Tom", "Ben", "Gil", "Adam", "Moshe", "Adi", "Michael", "Yasmin", "Jessica", "Caroline", "Avi", "Yael"};

        students.add(new Student());
        students.add(new Student());
        students.add(new Student());

        adapter = new listviewAdapter(this, students, names);
        listView = (ListView) findViewById(R.id.listView);
        listView.setAdapter(adapter);

    }

    public void updateStatus(int position)
    {
        View convertView = listView.getChildAt(position - listView.getFirstVisiblePosition());
        TextView tvValue = (TextView) convertView.findViewById(R.id.tv_Value);
        Spinner spName = (Spinner) convertView.findViewById(R.id.spNames);
        Spinner spGrade = (Spinner) convertView.findViewById(R.id.spGrades);

        tvValue.setText(spName.getSelectedItem().toString() + " got " + spGrade.getSelectedItem().toString());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_Add)
        {
            students.add(new Student());
            adapter.notifyDataSetChanged();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

listviewAdapter.java

public class listviewAdapter extends BaseAdapter
{
    public Activity context;
    public LayoutInflater inflater;

    private ArrayList<Student> studentID;
    private String[] studentsNames;

    public listviewAdapter(Activity context, ArrayList<Student> students, String[] names)
    {
        super();
        studentID = students;
        studentsNames = names;

        this.context = context;
        this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

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

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


    @Override
    public int getViewTypeCount() {
        return studentID.size() + 1;
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    public class ViewHolder {
        Spinner spNames, spGrades;
        TextView tvValue;
        Button btnSet, btnRemove;
    }

    @Override
    public View getView(int i, View view, final ViewGroup viewGroup)
    {
        final ViewHolder holder;
        if (view == null) {
            holder = new ViewHolder();
            view = inflater.inflate(R.layout.listview_row, null);

            holder.spNames = (Spinner) view.findViewById(R.id.spNames);
            holder.spGrades = (Spinner) view.findViewById(R.id.spGrades);
            holder.tvValue = (TextView) view.findViewById(R.id.tv_Value);
            holder.btnSet = (Button) view.findViewById(R.id.btn_setValue);
            holder.btnRemove = (Button) view.findViewById(R.id.btn_Remove);
            view.setTag(holder);
            holder.spNames.setTag(0);
            holder.spGrades.setTag(0);
        }
        else{
            holder = (ViewHolder) view.getTag();
        }

        // pop spinner names
        ArrayAdapter<String> studentsNamesAdapater = new ArrayAdapter<>
                (view.getContext(), android.R.layout.simple_spinner_dropdown_item, studentsNames);
        studentsNamesAdapater.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        holder.spNames.setAdapter(studentsNamesAdapater);

        // pop spinner grades
        String[] grades = new String[101];
        for (int grade = 0; grade < 101; grade++)
            grades[grade] = String.valueOf(grade);

        final ArrayAdapter<String> studentsGradesAdapter = new ArrayAdapter<>
                (view.getContext(), android.R.layout.simple_spinner_dropdown_item, grades);
        studentsGradesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        holder.spGrades.setAdapter(studentsGradesAdapter);


        // select the right spNames index
        holder.spNames.setSelection((Integer) holder.spNames.getTag());
        // saving spinner index
        holder.spNames.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                holder.spNames.setTag(position);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        // select the right spGrades index
        holder.spGrades.setSelection((Integer) holder.spGrades.getTag());
        // saving spinner index
        holder.spGrades.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                holder.spGrades.setTag(position);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        // set (variable and textview)
        holder.btnSet.setTag(i);
        holder.btnSet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // update studentID
                int position = (Integer) v.getTag();
                Student tmp = new Student(holder.spNames.getSelectedItem().toString(), Integer.valueOf(holder.spGrades.getSelectedItem().toString()));
                studentID.set(position, tmp);
                ((MainActivity) context).updateStatus(position);
            }
        });


        // remove row
        holder.btnRemove.setTag(i);
        holder.btnRemove.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = (Integer) v.getTag();
                studentID.remove(position);
                //notifyDataSetChanged();
                ((MainActivity) context).adapter.notifyDataSetChanged();

                // for debug
                String dStatus = "Vector size: " + studentID.size() + "\n";
                for (int index = 0; index < studentID.size(); index++)
                    dStatus += studentID.get(index).name + " " + studentID.get(index).grade + "\n";
                Toast.makeText(v.getContext(), dStatus, Toast.LENGTH_SHORT).show();
            }
        });

        return view;
    }
}

My problem is that the GUI does not update correctly, the deleted item on the GUI still appears on the screen as you can see below:

Can someone guide me please on how to remove the right row also from the GUI?

EDIT

  1. I update my listview Adapter and use Tags as you answer me, not working.
  2. I also found strange issue when I'm trying to add to Student after remove one. For some reason, it "remember" the last student and return him with full data, as you can see in the update picture.

EDIT2

In case someone want to try it, I add Student class and XML sources:

Student.java

public class Student
{
    public String name;
    public int grade;

    public Student()
    {
        name = "";
        grade = 0;
    }

    public Student(String _name, int _grade)
    {
        name = _name;
        grade = _grade;
    }
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/listView"
        android:layout_gravity="center_horizontal"
        android:dividerHeight="2dp" />
</LinearLayout>

listview_row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#c4e0ff">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

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

        <Spinner
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:id="@+id/spGrades"
            android:layout_marginLeft="10dp" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Set Value"
            android:id="@+id/btn_setValue" />
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="Medium Text"
            android:id="@+id/tv_Value" />

        <Button
            style="?android:attr/buttonStyleSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Remove"
            android:id="@+id/btn_Remove"
            android:layout_marginLeft="30dp" />

    </LinearLayout>

</LinearLayout>

解决方案

The problem is with

holder.spNames.setTag(position); 

and

holder.spNames.setSelection((Integer) holder.spNames.getTag());

As you are setting the tag for name in "onItemSelected()". When you delete the item you remove the item from the list of student, but what about the tag.

Let us say you deleted the item at 0.

Now, when "notifyDataSetChanged()" is called it will repopulate the listview based on the data is available. Now , here

else{
        holder = (ViewHolder) view.getTag();
    }

is getting called. When the i= 0 in getView() you will get the view of the "0 th" index of the previous populated list. Hence, the "(Integer) holder.spNames.getTag()" will point to the previous tag (i.e. 0 of the previous list) . This might be the cause of the issue.

I am posting updated code of

listviewAdapter

public class ListviewAdapter extends BaseAdapter
{
public Activity context;
public LayoutInflater inflater;
private ArrayList<Student> studentID;
private String[] studentsNames;
private boolean isDeleted;
public ListviewAdapter(Activity context, ArrayList<Student> students, String[] names)
{
    super();
    studentID = students;
    studentsNames = names;

    this.context = context;
    this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

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

@Override
public Student getItem(int position) {
    return studentID.get(position);
}

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




public class ViewHolder {
    Spinner spNames, spGrades;
    TextView tvValue;
    Button btnSet, btnRemove;
    int index;
}

@Override
public View getView(int i, View view, final ViewGroup viewGroup)
{
    final ViewHolder holder;
    if (view == null) {
        holder = new ViewHolder();
        view = inflater.inflate(R.layout.listview_row, null);

        holder.spNames = (Spinner) view.findViewById(R.id.spNames);
        holder.spGrades = (Spinner) view.findViewById(R.id.spGrades);
        holder.tvValue = (TextView) view.findViewById(R.id.tv_Value);
        holder.btnSet = (Button) view.findViewById(R.id.btn_setValue);
        holder.btnRemove = (Button) view.findViewById(R.id.btn_Remove);
        Log.e("IAM", "CALLED");
        view.setTag(holder);
        //holder.spNames.setTag(0);
        //holder.spGrades.setTag(0);
    }
    else{
        holder = (ViewHolder) view.getTag();
    }
    holder.index=i;
   if(isDeleted){
       holder.tvValue.setText(getItem(holder.index).getName()+ " got " + getItem(holder.index).getGrade()); 
            }
    // pop spinner names
    ArrayAdapter<String> studentsNamesAdapater = new ArrayAdapter<String>
            (view.getContext(), android.R.layout.simple_spinner_dropdown_item, studentsNames);
    studentsNamesAdapater.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    holder.spNames.setAdapter(studentsNamesAdapater);

    // pop spinner grades
    String[] grades = new String[101];
    for (int grade = 0; grade < 101; grade++)
        grades[grade] = String.valueOf(grade);

    final ArrayAdapter<String> studentsGradesAdapter = new ArrayAdapter<String>
            (view.getContext(), android.R.layout.simple_spinner_dropdown_item, grades);
    studentsGradesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    holder.spGrades.setAdapter(studentsGradesAdapter);


    // select the right spNames index
    //holder.spNames.setSelection((Integer) holder.spNames.getTag());
    holder.spNames.setSelection(getItem(holder.index).getNameIndex());
    // saving spinner index
    holder.spNames.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            //holder.spNames.setTag(position);
            getItem(holder.index).setNameIndex(position);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });

    // select the right spGrades index
   // holder.spGrades.setSelection((Integer) holder.spGrades.getTag());

    holder.spGrades.setSelection(getItem(holder.index).getGrageIndex());
    // saving spinner index
    holder.spGrades.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
           // holder.spGrades.setTag(position);
            getItem(holder.index).setGrageIndex(position);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });

    // set (variable and textview)
    holder.btnSet.setTag(i);
    holder.btnSet.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // update studentID
            //final int position = getRowPosition(v);
            int position = (Integer) v.getTag();
           // Student tmp = new Student(holder.spNames.getSelectedItem().toString(), Integer.valueOf(holder.spGrades.getSelectedItem().toString()));
           // studentID.set(position, tmp);
            getItem(position).setName(holder.spNames.getSelectedItem().toString());
            getItem(position).setGrade(Integer.valueOf(holder.spGrades.getSelectedItem().toString()));
            holder.tvValue.setText(getItem(position).getName()+ " got " + getItem(position).getGrade());
            //((MainActivity) context).updateStatus(position);
        }
    });


    // remove row
    holder.btnRemove.setTag(i);
    holder.btnRemove.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //final int position = getRowPosition(v);
            int position = (Integer) v.getTag();
            studentID.remove(position);
            notifyDataSetChanged();
            //((MainActivity) context).adapter.notifyDataSetChanged();
            isDeleted=true;
            // for debug
            String dStatus = "Vector size: " + studentID.size() + "\n";
            for (int index = 0; index < studentID.size(); index++)
                dStatus += studentID.get(index).name + " " + studentID.get(index).grade + "\n";
            Toast.makeText(v.getContext(), dStatus, Toast.LENGTH_SHORT).show();
        }
    });

    return view;
}

public void printS() {
    for (int i = 0; i <studentID.size(); i++) {
        Log.e("NAME", ""+studentID.get(i).getName());
        Log.e("GRADE", ""+studentID.get(i).getGrade());
    }
}
}

and

Student

public class Student {
public String name;
public int grade;
private int nameIndex;
private int grageIndex;

public Student()
{
    name = "";
    grade = 0;
}

public Student(String _name, int _grade)
{
    name = _name;
    grade = _grade;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getGrade() {
    return grade;
}

public void setGrade(int grade) {
    this.grade = grade;
}

public int getNameIndex() {
    return nameIndex;
}

public void setNameIndex(int nameIndex) {
    this.nameIndex = nameIndex;
}

public int getGrageIndex() {
    return grageIndex;
}

public void setGrageIndex(int grageIndex) {
    this.grageIndex = grageIndex;
}
}

这篇关于错行从微调定制列表视图中删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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