在android中以编程方式添加列表项

时间:2018-03-13 15:48:49

标签: android listview

我正在开发一个基本应用

在此应用程序中,该列表是用户可以添加到其个人资料中的技能

我想做的是:

为项目创建一个xml文件,用户可以在其中输入所有数据(完成)

创建一个自定义适配器,可以将这些.xml文件呈现为listview(已完成)

创建一个按钮,当按下该按钮时,将呈现一个新的项目槽,允许用户输入他的另一项技能(已完成)

问题是:每次我点击按钮添加新技能时,它都会删除先前技能插槽中输入的所有数据。我已经尝试使用onNotifyDataSetChanged无济于事。

如何在不删除我在其他所有项目上设置的数据的情况下,以编程方式将新项目添加到列表视图中

例如,它与手机通讯录应用程序完全相同,每个联系人都可以有多个电话号码/电子邮件等等

适配器代码:

package br.com.jobr.jobr.Utils.Adapter;

import android.content.Context;
import android.graphics.Color;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

import br.com.jobr.jobr.Entities.Support.Skill;
import br.com.jobr.jobr.R;

/**
 * Created by christian.hess on 13/03/2018.
 */

public class NewSkillAdapter extends ArrayAdapter<Skill> {

    Context context;
    int resource;
    List<Skill> skills;
    ListView listSkills;

    public NewSkillAdapter(@NonNull Context context, int resource, List<Skill> skills, ListView listSkills) {
        super(context, resource, skills);
        Log.i("NewSkill", "Numero de item: " + skills.size());
        this.resource = resource;
        this.context = context;
        this.skills = skills;
        this.listSkills = listSkills;
    }


    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        View item = inflater.inflate(resource, parent, false);

        final Button bt_new_skill = item.findViewById(R.id.bt_new_skill);
        final Spinner sp_skill_name = item.findViewById(R.id.sp_skill_name);
        final Spinner sp_skill_specialization = item.findViewById(R.id.sp_skill_specialization);


        String[] habilityArray = context.getResources().getStringArray(R.array.hability_array);
        ArrayAdapter<String> habilityAdapter = new ArrayAdapter<String>(
                context, android.R.layout.simple_spinner_item, habilityArray) {
            @Override
            public boolean isEnabled(int position) {
                if (position == 0) {
                    // Disable the first item from Spinner
                    // First item will be use for hint
                    return false;
                } else {
                    return true;
                }
            }

            @Override
            public View getDropDownView(int position, View convertView,
                                        ViewGroup parent) {
                View view = super.getDropDownView(position, convertView, parent);
                TextView tv = (TextView) view;
                if (position == 0) {
                    // Set the hint text color gray
                    tv.setTextColor(Color.GRAY);
                } else {
                    tv.setTextColor(Color.BLACK);
                }
                return view;
            }
        };
        habilityAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        sp_skill_name.setAdapter(habilityAdapter);


        String[] especializationArray = context.getResources().getStringArray(R.array.especialization_array);
        ArrayAdapter<String> especializationAdapter = new ArrayAdapter<String>(
                context, android.R.layout.simple_spinner_item, especializationArray) {
            @Override
            public boolean isEnabled(int position) {
                if (position == 0) {
                    // Disable the first item from Spinner
                    // First item will be use for hint
                    return false;
                } else {
                    return true;
                }
            }

            @Override
            public View getDropDownView(int position, View convertView,
                                        ViewGroup parent) {
                View view = super.getDropDownView(position, convertView, parent);
                TextView tv = (TextView) view;
                if (position == 0) {
                    // Set the hint text color gray
                    tv.setTextColor(Color.GRAY);
                } else {
                    tv.setTextColor(Color.BLACK);
                }
                return view;
            }
        };
        especializationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        sp_skill_specialization.setAdapter(especializationAdapter);


        bt_new_skill.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int size = skills.size();
                skills = new ArrayList<>();
                for (int i = 0; i < size; i++) {
                    Skill s = (Skill) listSkills.getAdapter().getItem(i);
                    skills.add(s);
                }

                skills.add(new Skill("", "", "", ""));
                listSkills.getAdapter().notifyAll();
            }
        });

        return item;
    }
}

1 个答案:

答案 0 :(得分:0)

这种行为让我相信每次添加新技能时都会清除适配器上的数据结构。 你可以发布你的适配器代码片段,以便我们直观地调试吗?

此致

@Edit

我相信你的问题就在这条特定的路线上

            skills = new ArrayList<>();

在你的

里面
bt_new_skill.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int size = skills.size();
            skills = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                Skill s = (Skill) listSkills.getAdapter().getItem(i);
                skills.add(s);
            }

            skills.add(new Skill("", "", "", ""));
            listSkills.getAdapter().notifyAll();
        }
    });

正如您所看到的,每当您按下&#34; bt_new_skill&#34;按钮,您正在重新初始化ArrayList,从而丢失所有以前的记录。 我并不完全了解你的代码,所以如果它没有解决,请记住它。

另外,我建议您使用

listSkills.getAdapter().notifyDataSetChanged();

而不是

listSkills.getAdapter().notifyAll();

因为前者是更新适配器数据集的官方方法