【问题标题】:Another List inside my Custom Listview with Firebase我的自定义列表视图中的另一个列表与 Firebase
【发布时间】:2019-01-26 06:24:57
【问题描述】:

我正在尝试在我的自定义列表视图中显示另一个列表,如下图所示。我已成功显示前三个孩子(姓名、运动和城镇)。但是当我添加覆盖子时,我在主要活动中收到此错误“无法将类型数组列表的值转换为字符串”。

错误信息

Failed to convert value of type java.util.ArrayList to String

这是我试图实现的显示 This is what im trying to achieve

这是我的 firebase 数据库结构 db structure

我的主要活动的代码如下

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

    mListView = (ListView)findViewById(R.id.cusListView);
    mTextView = (TextView)findViewById(R.id.textV);

    mRef = FirebaseDatabase.getInstance().getReference().child("Person");
        mRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                showData(dataSnapshot);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

}

private void showData(DataSnapshot dataSnapshot){

    ArrayList<PeopleGetSet> array = new ArrayList<>();

    for(DataSnapshot ds : dataSnapshot.getChildren()) {
        PeopleGetSet arr = ds.getValue(PeopleGetSet.class);

        array.add(arr);

        ViewDatabase adapter = new ViewDatabase(this, R.layout.adapter_view_layout, array);
        mListView.setAdapter(adapter);

    }

}

这是我的适配器代码

public class ViewDatabase extends ArrayAdapter<PeopleGetSet> {
private static final String TAG="ViewDatabase";
private Context mContext;
int mResource;

public ViewDatabase(@NonNull Context context, int resource, @NonNull List<PeopleGetSet> objects) {
    super(context, resource, objects);
    this.mContext=context;
    mResource = resource;
}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    String name =getItem(position).getName();
    String sport =getItem(position).getSport();
    String town =getItem(position).getTown();
    String Coverage =getItem(position).getCoverage();
    PeopleGetSet person = new PeopleGetSet(name,sport, town, Coverage);

    LayoutInflater inflater = LayoutInflater.from(mContext);
    convertView=inflater.inflate(mResource, parent, false);

    TextView tvName = (TextView)convertView.findViewById(R.id.textView);
    TextView tvSport = (TextView)convertView.findViewById(R.id.textView2);
    TextView tvTown = (TextView)convertView.findViewById(R.id.textView3);
    TextView tvCoverage = (TextView)convertView.findViewById(R.id.textView4);

    tvName.setText(name);
    tvSport.setText(sport);
    tvTown.setText(town);
    tvCoverage.setText(Coverage);
    return convertView;
   }

}

这是我的 Getter 和 setter 代码

public class PeopleGetSet {
private String name;
private String sport;
private String town;
private String Coverage;

public PeopleGetSet() {

}

public PeopleGetSet(String name, String sport, String town, String Coverage) {
    this.name = name;
    this.sport = sport;
    this.town = town;
    this.Coverage = Coverage;
}

public String getName() {
    return name;
}

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

public String getSport() {
    return sport;
}

public void setSport(String sport) {
    this.sport = sport;
}

public String getTown() {
    return town;
}

public void setTown(String town) {
    this.town = town;
}

public String getCoverage() {
    return Coverage;
}

public void setCoverage(String coverage) {
    Coverage = coverage;
   }
}

【问题讨论】:

  • 我认为这里的模型有问题private String Coverage; 可能它必须是包含字符串列表的对象。
  • 你的意思是像ExpandableListView这样的两级列表吗?
  • 字符串覆盖率必须是arraylist?
  • 看我的回答

标签: android firebase listview arraylist firebase-realtime-database


【解决方案1】:

我的意思是这样的:

public class PeopleGetSet {
   private String name;
   private String sport;
   private String town;
   private Coverage coverage; 
    ... default code
}

public class Coverage {
   private ArrayList<String> names;
   ... default code
}

【讨论】:

  • 没有参数、getter 和 setter 的类构造函数
  • public PeopleGetSet(String name, String sport, String town, ArrayList&lt;String&gt; Coverage) { this.name = name; this.sport = sport; this.town = town; this.Coverage = Coverage; } 我应该在代码行中删除这个覆盖吗?
  • 如果您需要带参数的构造函数,则无需删除它。对于从 firebase 映射对象,您需要不带参数的默认构造函数,如果需要,您可以使用这个构造函数
【解决方案2】:

问题出在您的 Getter Setter 类中 将 Coverage 添加为您的 PeopleGetSet 类中的 Hashmap。 Coverage 不是其数组的字符串,因此要从 firebase 读取数组,您应该使用 HashMap

      public class PeopleGetSet {
      private String name;
      private String sport;
      private String town;
      private HashMap<String,String> Coverage ;

      public PeopleGetSet() {

       }

     public PeopleGetSet(String name, String sport, String town,  HashMap<String, String> Coverage) {
      this.name = name;
      this.sport = sport;
      this.town = town;
     this.Coverage = Coverage;
     }

    public String getName() {
    return name;
    }

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

    public String getSport() {
      return sport;
    }

   public void setSport(String sport) {
    this.sport = sport;
   }

    public String getTown() {
       return town;
     }

public  HashMap<String,String> getCoverage() {
       return Coverage;
     }

【讨论】:

  • 我在适配器中将字符串覆盖范围更改为Map Coverage =getItem(position).getCoverage();,并在此行PeopleGetSet person = new PeopleGetSet(name,sport, town, Coverage); 和此处tvCoverage.setText(Coverage); 出现错误
  • 你先试试这段代码,它会运行。我已经在 2 个应用程序中正常运行了。
  • 我的适配器出现了这个错误,这行代码无法运行String Coverage =getItem(position).getCoverage();PeopleGetSet person = new PeopleGetSet(name,sport, town, Coverage);
  • 我已经告诉过你了,它不是字符串而是 hashmap 键值对。
  • 是的,我将其更改为 Hashmap。并使用此代码 settext `tvCoverage.setText((CharSequence) Coverage);` 并得到这个新的错误消息 Expected a Map while deserializing, but got a class java.util.ArrayList
【解决方案3】:

有一种简单的方法可以在一个 ListView 中扩展多个视图。这是我的示例代码。

public class MyExampleCode extends ArrayAdapter<Object> {

private static final int TYPE_1 = 0;
private static final int TYPE_2 = 1;

private Context context;
private List<Object> objectList;

public MyExampleCode(Context context, List<Object> objectList) {
    super(context,layout,objectList);

    this.context = context;
    this.objectList = objectList;
}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

    if (getItemViewType(position) == TYPE_1) {

        PeopleGetSet peopleGetSet = (PeopleGetSet)objectList.get(position);
        //handle code for first object, inflate layout and fill it
    } else {

        Coverage coverage = (Coverage)objectList.get(position);
        //handle code for second object, inflate layout and fill it
    }
}

@Override
public int getItemViewType(int position) {

    if (getItem(position) instanceof PeopleGetSet) {

        return TYPE_1;
    } else {

        return TYPE_2;
    }
}

@Nullable
@Override
public Object getItem(int position) {

    return objectList.get(position);
}

@Override
public int getCount() {

    return objectList.size();
}

}

@编辑
让我们更新您的代码

private void showData(DataSnapshot dataSnapshot){

    List<Object> array = new ArrayList<>();

    for(DataSnapshot ds : dataSnapshot.getChildren()) {
        PeopleGetSet arr = ds.getValue(PeopleGetSet.class);
        Coverage arr2 = arr.getCoverage();

        array.add(arr);
        array.add(arr2);
    }
    ViewDatabase adapter = new ViewDatabase(this, array);
    mListView.setAdapter(adapter);
}

【讨论】:

  • 我会添加另一个适配器类吗?并且不会更改我现有代码的任何内容?
  • 让你的适配器更改Object的源,覆盖getItemViewType(int position)方法,在那里添加ifstatement,并将getView中的代码移动到第一个条件。现在,让我们为Coverage 模型创建一个新的布局资源,将其膨胀并从Coverage 对象填充。我已经为您的 showData() 方法更新了代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-27
  • 1970-01-01
  • 2014-11-02
  • 2011-10-13
  • 1970-01-01
相关资源
最近更新 更多