列表视图无法正确获取数据
listview not getting data correctly
好的,所以我在我的 android 应用程序中有一个 listView 来显示消息,自从我及时得到帮助以来一切都很好,但现在我遇到了一个错误,最后一条消息不会显示。
消息部分如果是“系统”消息则不会显示。这与 firebase 相关联。
但是当我获取数据时,除了消息类型之外,它对每个项目都适用。
// this is what the message looks like in the database
"messages": "hi",
"number": "1",
"pfp": "",
"time": "2022-04-22T00:39:00.520Z",
// this tells the app what type of message it is
"type": "user",
"user_uid": "user id",
"username": "frugalnormal"
甚至切换到回收视图和同样的事情
注意:我只是敬酒告诉我它是否认为该消息是系统消息并且每次都确定enter image description here我发送了一条“用户”消息它告诉我这是一个系统消息并且不会显示那部分但仍然可以显示时间
时间也应该出现在短信上
更新:
好吧,现在我已经厌倦了最后一条消息显示的所有内容,但应用程序仍然认为最后一条消息始终是“系统”消息
所以开关 returns 都不知何故
“用户”和“系统”出于某种原因
更新2:
所以现在我真的很困惑,滚动浏览它会使系统消息随机发生在不同的消息上
更新 3
//////////////////////////////////////////////// ////////////////////////////
整个适配器的代码:
这是为了将数据应用到视图:
_ch_child_listener = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot _param1, String _param2) {
GenericTypeIndicator<HashMap<String, Object>> _ind = new GenericTypeIndicator<HashMap<String, Object>>() {};
final String _childKey = _param1.getKey();
final HashMap<String, Object> _childValue = _param1.getValue(_ind);
ch.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot _dataSnapshot) {
lop = new ArrayList<>();
try {
GenericTypeIndicator<HashMap<String, Object>> _ind = new GenericTypeIndicator<HashMap<String, Object>>() {};
for (DataSnapshot _data : _dataSnapshot.getChildren()) {
HashMap<String, Object> _map = _data.getValue(_ind);
lop.add(_map);
}
}
catch (Exception _e) {
_e.printStackTrace();
}
listview2.setAdapter(new Listview2Adapter(lop));
((BaseAdapter)listview2.getAdapter()).notifyDataSetChanged();
x.add(_childKey);
}
剩下的是:
public class Listview2Adapter extends BaseAdapter {
ArrayList<HashMap<String, Object>> _data;
public Listview2Adapter(ArrayList<HashMap<String, Object>> _arr) {
_data = _arr;
}
@Override
public int getCount() {
return _data.size();
}
@Override
public HashMap<String, Object> getItem(int _index) {
return _data.get(_index);
}
@Override
public long getItemId(int _index) {
return _index;
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public View getView(final int _position, View _v, ViewGroup _container) {
LayoutInflater _inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View _view = _v;
if (_view == null) {
_view = _inflater.inflate(R.layout.messgebubble, listview2, false);
}
final LinearLayout time = _view.findViewById(R.id.time);
final TextView textview1 = _view.findViewById(R.id.textview1);
final LinearLayout linear4 = _view.findViewById(R.id.linear4);
final TextView timetext = _view.findViewById(R.id.timetext);
final LinearLayout left = _view.findViewById(R.id.left);
final LinearLayout linear1 = _view.findViewById(R.id.linear1);
final de.hdodenhof.circleimageview.CircleImageView circleimageview1 = _view.findViewById(R.id.circleimageview1);
final TextView message = _view.findViewById(R.id.message);
final ImageView imageview1 = _view.findViewById(R.id.imageview1);
final TextView SystemText = _view.findViewById(R.id.systemtext);
final LinearLayout system = _view.findViewById(R.id.system);
Instant i = Instant.parse(_data.get(_position).get("time").toString());
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").withZone(ZoneId.systemDefault());;
String Time = dateTimeFormatter.format(i);
timetext.setText(Time);
String messageType = lop.get(_position).get("type").toString();
switch (messageType){
case "system":
SystemText.setText(_data.get(_position).get("messages").toString());
Toast.makeText(GroupChatActiviy.this, "This is a system message", Toast.LENGTH_SHORT).show();
system.setVisibility(View.VISIBLE);
break;
case "user":
linear4.setVisibility(View.VISIBLE);
if (_data.get((int)_position).get("messages").toString().equals("")) {
if (_data.get((int)_position).containsKey("image")) {
imageview1.setVisibility(View.VISIBLE);
if (_data.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
linear4.setGravity(Gravity.RIGHT);
linear1.setGravity(Gravity.RIGHT);
}
else {
linear4.setGravity(Gravity.LEFT);
linear1.setGravity(Gravity.LEFT);
}
}
else {
}
}
else {
message.setText(_data.get((int)_position).get("messages").toString());
message.setVisibility(View.VISIBLE);
if (lop.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
linear4.setGravity(Gravity.RIGHT);
linear1.setGravity(Gravity.RIGHT);
linear1.setBackgroundResource(R.drawable.start);
}
else {
linear4.setGravity(Gravity.LEFT);
linear1.setGravity(Gravity.LEFT);
linear1.setBackgroundResource(R.drawable.right);
}
if (_data.get((int)_position).containsKey("image")) {
imageview1.setVisibility(View.VISIBLE);
}
else {
}
}
String LastTimeText = _data.get((int)_position - 1).get("time").toString();
Instant LastI = Instant.parse(LastTimeText);
Duration Dur = Duration.between(LastI, i);
if (Dur.getSeconds() <= 600) {
}
else {
if (lop.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
}
else {
circleimageview1.setVisibility(View.VISIBLE);
textview1.setVisibility(View.VISIBLE);
//Glide.with(getApplicationContext()).load(Uri.parse(_data.get((int)_position).get("pfp").toString())).into(circleimageview1);
textview1.setText(_data.get((int)_position).get("username").toString());
}
time.setVisibility(View.VISIBLE);
}
break;
}
if(_data.get((int)_position).get("number") != null){
if (_data.get((int)_position).get("number").toString().equals("")) {
}
else {
if (Numberrr < Double.parseDouble(_data.get((int)_position).get("number").toString())) {
Numberrr = Double.parseDouble(_data.get((int)_position).get("number").toString()) + 1;
}
}
}
return _view;
}
}
问题可能是可见的,每当项目渲染时,我们应该始终隐藏所有内容,就像您可以创建组 user
和 system
并首先隐藏 it.on 每个绑定视图的所有视图我们将首先隐藏所有内容,并根据打开的数据使特定的所有视图可见,然后进行数据设置。
在适配器的 get View 方法中执行如下代码
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public View getView(final int _position, View _v, ViewGroup _container) {
LayoutInflater _inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View _view = _v;
if (_view == null) {
_view = _inflater.inflate(R.layout.messgebubble, listview2, false);
}
final LinearLayout time = _view.findViewById(R.id.time);
final TextView textview1 = _view.findViewById(R.id.textview1);
final LinearLayout linear4 = _view.findViewById(R.id.linear4);
final TextView timetext = _view.findViewById(R.id.timetext);
final LinearLayout left = _view.findViewById(R.id.left);
final LinearLayout linear1 = _view.findViewById(R.id.linear1);
final de.hdodenhof.circleimageview.CircleImageView circleimageview1 = _view.findViewById(R.id.circleimageview1);
final TextView message = _view.findViewById(R.id.message);
final ImageView imageview1 = _view.findViewById(R.id.imageview1);
final TextView SystemText = _view.findViewById(R.id.systemtext);
final LinearLayout system = _view.findViewById(R.id.system);
time.setVisibility(View.GONE);
textview1.setVisibility(View.GONE);
linear4.setVisibility(View.GONE);
timetext.setVisibility(View.GONE);
left.setVisibility(View.GONE);
linear1.setVisibility(View.GONE);
circleimageview1.setVisibility(View.GONE);
message.setVisibility(View.GONE);
imageview1.setVisibility(View.GONE);
SystemText.setVisibility(View.GONE);
system.setVisibility(View.GONE);
Instant i = Instant.parse(_data.get(_position).get("time").toString());
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").withZone(ZoneId.systemDefault());;
String Time = dateTimeFormatter.format(i);
timetext.setText(Time);
String messageType = lop.get(_position).get("type").toString();
switch (messageType){
case "system":
SystemText.setText(_data.get(_position).get("messages").toString());
Toast.makeText(GroupChatActiviy.this, "This is a system message", Toast.LENGTH_SHORT).show();
system.setVisibility(View.VISIBLE);
break;
case "user":
linear4.setVisibility(View.VISIBLE);
if (_data.get((int)_position).get("messages").toString().equals("")) {
if (_data.get((int)_position).containsKey("image")) {
imageview1.setVisibility(View.VISIBLE);
if (_data.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
linear4.setGravity(Gravity.RIGHT);
linear1.setGravity(Gravity.RIGHT);
}
else {
linear4.setGravity(Gravity.LEFT);
linear1.setGravity(Gravity.LEFT);
}
}
else {
}
}
else {
message.setText(_data.get((int)_position).get("messages").toString());
message.setVisibility(View.VISIBLE);
if (lop.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
linear4.setGravity(Gravity.RIGHT);
linear1.setGravity(Gravity.RIGHT);
linear1.setBackgroundResource(R.drawable.start);
}
else {
linear4.setGravity(Gravity.LEFT);
linear1.setGravity(Gravity.LEFT);
linear1.setBackgroundResource(R.drawable.right);
}
if (_data.get((int)_position).containsKey("image")) {
imageview1.setVisibility(View.VISIBLE);
}
else {
}
}
String LastTimeText = _data.get((int)_position - 1).get("time").toString();
Instant LastI = Instant.parse(LastTimeText);
Duration Dur = Duration.between(LastI, i);
if (Dur.getSeconds() <= 600) {
}
else {
if (lop.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
}
else {
circleimageview1.setVisibility(View.VISIBLE);
textview1.setVisibility(View.VISIBLE);
//Glide.with(getApplicationContext()).load(Uri.parse(_data.get((int)_position).get("pfp").toString())).into(circleimageview1);
textview1.setText(_data.get((int)_position).get("username").toString());
}
time.setVisibility(View.VISIBLE);
}
break;
}
if(_data.get((int)_position).get("number") != null){
if (_data.get((int)_position).get("number").toString().equals("")) {
}
else {
if (Numberrr < Double.parseDouble(_data.get((int)_position).get("number").toString())) {
Numberrr = Double.parseDouble(_data.get((int)_position).get("number").toString()) + 1;
}
}
}
return _view;
}
您的适配器基于 _data
,但正在从 lop
获取消息类型。随着新数据的进入,这两者可能会周期性地失去同步。确保您的适配器仅访问来自 _data
的行项目信息,并且它应该按预期工作。
好的,所以我在我的 android 应用程序中有一个 listView 来显示消息,自从我及时得到帮助以来一切都很好,但现在我遇到了一个错误,最后一条消息不会显示。
消息部分如果是“系统”消息则不会显示。这与 firebase 相关联。
但是当我获取数据时,除了消息类型之外,它对每个项目都适用。
// this is what the message looks like in the database
"messages": "hi",
"number": "1",
"pfp": "",
"time": "2022-04-22T00:39:00.520Z",
// this tells the app what type of message it is
"type": "user",
"user_uid": "user id",
"username": "frugalnormal"
甚至切换到回收视图和同样的事情
注意:我只是敬酒告诉我它是否认为该消息是系统消息并且每次都确定enter image description here我发送了一条“用户”消息它告诉我这是一个系统消息并且不会显示那部分但仍然可以显示时间
时间也应该出现在短信上
更新: 好吧,现在我已经厌倦了最后一条消息显示的所有内容,但应用程序仍然认为最后一条消息始终是“系统”消息
所以开关 returns 都不知何故 “用户”和“系统”出于某种原因
更新2: 所以现在我真的很困惑,滚动浏览它会使系统消息随机发生在不同的消息上
更新 3 //////////////////////////////////////////////// //////////////////////////// 整个适配器的代码:
这是为了将数据应用到视图:
_ch_child_listener = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot _param1, String _param2) {
GenericTypeIndicator<HashMap<String, Object>> _ind = new GenericTypeIndicator<HashMap<String, Object>>() {};
final String _childKey = _param1.getKey();
final HashMap<String, Object> _childValue = _param1.getValue(_ind);
ch.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot _dataSnapshot) {
lop = new ArrayList<>();
try {
GenericTypeIndicator<HashMap<String, Object>> _ind = new GenericTypeIndicator<HashMap<String, Object>>() {};
for (DataSnapshot _data : _dataSnapshot.getChildren()) {
HashMap<String, Object> _map = _data.getValue(_ind);
lop.add(_map);
}
}
catch (Exception _e) {
_e.printStackTrace();
}
listview2.setAdapter(new Listview2Adapter(lop));
((BaseAdapter)listview2.getAdapter()).notifyDataSetChanged();
x.add(_childKey);
}
剩下的是:
public class Listview2Adapter extends BaseAdapter {
ArrayList<HashMap<String, Object>> _data;
public Listview2Adapter(ArrayList<HashMap<String, Object>> _arr) {
_data = _arr;
}
@Override
public int getCount() {
return _data.size();
}
@Override
public HashMap<String, Object> getItem(int _index) {
return _data.get(_index);
}
@Override
public long getItemId(int _index) {
return _index;
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public View getView(final int _position, View _v, ViewGroup _container) {
LayoutInflater _inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View _view = _v;
if (_view == null) {
_view = _inflater.inflate(R.layout.messgebubble, listview2, false);
}
final LinearLayout time = _view.findViewById(R.id.time);
final TextView textview1 = _view.findViewById(R.id.textview1);
final LinearLayout linear4 = _view.findViewById(R.id.linear4);
final TextView timetext = _view.findViewById(R.id.timetext);
final LinearLayout left = _view.findViewById(R.id.left);
final LinearLayout linear1 = _view.findViewById(R.id.linear1);
final de.hdodenhof.circleimageview.CircleImageView circleimageview1 = _view.findViewById(R.id.circleimageview1);
final TextView message = _view.findViewById(R.id.message);
final ImageView imageview1 = _view.findViewById(R.id.imageview1);
final TextView SystemText = _view.findViewById(R.id.systemtext);
final LinearLayout system = _view.findViewById(R.id.system);
Instant i = Instant.parse(_data.get(_position).get("time").toString());
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").withZone(ZoneId.systemDefault());;
String Time = dateTimeFormatter.format(i);
timetext.setText(Time);
String messageType = lop.get(_position).get("type").toString();
switch (messageType){
case "system":
SystemText.setText(_data.get(_position).get("messages").toString());
Toast.makeText(GroupChatActiviy.this, "This is a system message", Toast.LENGTH_SHORT).show();
system.setVisibility(View.VISIBLE);
break;
case "user":
linear4.setVisibility(View.VISIBLE);
if (_data.get((int)_position).get("messages").toString().equals("")) {
if (_data.get((int)_position).containsKey("image")) {
imageview1.setVisibility(View.VISIBLE);
if (_data.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
linear4.setGravity(Gravity.RIGHT);
linear1.setGravity(Gravity.RIGHT);
}
else {
linear4.setGravity(Gravity.LEFT);
linear1.setGravity(Gravity.LEFT);
}
}
else {
}
}
else {
message.setText(_data.get((int)_position).get("messages").toString());
message.setVisibility(View.VISIBLE);
if (lop.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
linear4.setGravity(Gravity.RIGHT);
linear1.setGravity(Gravity.RIGHT);
linear1.setBackgroundResource(R.drawable.start);
}
else {
linear4.setGravity(Gravity.LEFT);
linear1.setGravity(Gravity.LEFT);
linear1.setBackgroundResource(R.drawable.right);
}
if (_data.get((int)_position).containsKey("image")) {
imageview1.setVisibility(View.VISIBLE);
}
else {
}
}
String LastTimeText = _data.get((int)_position - 1).get("time").toString();
Instant LastI = Instant.parse(LastTimeText);
Duration Dur = Duration.between(LastI, i);
if (Dur.getSeconds() <= 600) {
}
else {
if (lop.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
}
else {
circleimageview1.setVisibility(View.VISIBLE);
textview1.setVisibility(View.VISIBLE);
//Glide.with(getApplicationContext()).load(Uri.parse(_data.get((int)_position).get("pfp").toString())).into(circleimageview1);
textview1.setText(_data.get((int)_position).get("username").toString());
}
time.setVisibility(View.VISIBLE);
}
break;
}
if(_data.get((int)_position).get("number") != null){
if (_data.get((int)_position).get("number").toString().equals("")) {
}
else {
if (Numberrr < Double.parseDouble(_data.get((int)_position).get("number").toString())) {
Numberrr = Double.parseDouble(_data.get((int)_position).get("number").toString()) + 1;
}
}
}
return _view;
}
}
问题可能是可见的,每当项目渲染时,我们应该始终隐藏所有内容,就像您可以创建组 user
和 system
并首先隐藏 it.on 每个绑定视图的所有视图我们将首先隐藏所有内容,并根据打开的数据使特定的所有视图可见,然后进行数据设置。
在适配器的 get View 方法中执行如下代码
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public View getView(final int _position, View _v, ViewGroup _container) {
LayoutInflater _inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View _view = _v;
if (_view == null) {
_view = _inflater.inflate(R.layout.messgebubble, listview2, false);
}
final LinearLayout time = _view.findViewById(R.id.time);
final TextView textview1 = _view.findViewById(R.id.textview1);
final LinearLayout linear4 = _view.findViewById(R.id.linear4);
final TextView timetext = _view.findViewById(R.id.timetext);
final LinearLayout left = _view.findViewById(R.id.left);
final LinearLayout linear1 = _view.findViewById(R.id.linear1);
final de.hdodenhof.circleimageview.CircleImageView circleimageview1 = _view.findViewById(R.id.circleimageview1);
final TextView message = _view.findViewById(R.id.message);
final ImageView imageview1 = _view.findViewById(R.id.imageview1);
final TextView SystemText = _view.findViewById(R.id.systemtext);
final LinearLayout system = _view.findViewById(R.id.system);
time.setVisibility(View.GONE);
textview1.setVisibility(View.GONE);
linear4.setVisibility(View.GONE);
timetext.setVisibility(View.GONE);
left.setVisibility(View.GONE);
linear1.setVisibility(View.GONE);
circleimageview1.setVisibility(View.GONE);
message.setVisibility(View.GONE);
imageview1.setVisibility(View.GONE);
SystemText.setVisibility(View.GONE);
system.setVisibility(View.GONE);
Instant i = Instant.parse(_data.get(_position).get("time").toString());
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").withZone(ZoneId.systemDefault());;
String Time = dateTimeFormatter.format(i);
timetext.setText(Time);
String messageType = lop.get(_position).get("type").toString();
switch (messageType){
case "system":
SystemText.setText(_data.get(_position).get("messages").toString());
Toast.makeText(GroupChatActiviy.this, "This is a system message", Toast.LENGTH_SHORT).show();
system.setVisibility(View.VISIBLE);
break;
case "user":
linear4.setVisibility(View.VISIBLE);
if (_data.get((int)_position).get("messages").toString().equals("")) {
if (_data.get((int)_position).containsKey("image")) {
imageview1.setVisibility(View.VISIBLE);
if (_data.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
linear4.setGravity(Gravity.RIGHT);
linear1.setGravity(Gravity.RIGHT);
}
else {
linear4.setGravity(Gravity.LEFT);
linear1.setGravity(Gravity.LEFT);
}
}
else {
}
}
else {
message.setText(_data.get((int)_position).get("messages").toString());
message.setVisibility(View.VISIBLE);
if (lop.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
linear4.setGravity(Gravity.RIGHT);
linear1.setGravity(Gravity.RIGHT);
linear1.setBackgroundResource(R.drawable.start);
}
else {
linear4.setGravity(Gravity.LEFT);
linear1.setGravity(Gravity.LEFT);
linear1.setBackgroundResource(R.drawable.right);
}
if (_data.get((int)_position).containsKey("image")) {
imageview1.setVisibility(View.VISIBLE);
}
else {
}
}
String LastTimeText = _data.get((int)_position - 1).get("time").toString();
Instant LastI = Instant.parse(LastTimeText);
Duration Dur = Duration.between(LastI, i);
if (Dur.getSeconds() <= 600) {
}
else {
if (lop.get((int)_position).get("user_uid").toString().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
}
else {
circleimageview1.setVisibility(View.VISIBLE);
textview1.setVisibility(View.VISIBLE);
//Glide.with(getApplicationContext()).load(Uri.parse(_data.get((int)_position).get("pfp").toString())).into(circleimageview1);
textview1.setText(_data.get((int)_position).get("username").toString());
}
time.setVisibility(View.VISIBLE);
}
break;
}
if(_data.get((int)_position).get("number") != null){
if (_data.get((int)_position).get("number").toString().equals("")) {
}
else {
if (Numberrr < Double.parseDouble(_data.get((int)_position).get("number").toString())) {
Numberrr = Double.parseDouble(_data.get((int)_position).get("number").toString()) + 1;
}
}
}
return _view;
}
您的适配器基于 _data
,但正在从 lop
获取消息类型。随着新数据的进入,这两者可能会周期性地失去同步。确保您的适配器仅访问来自 _data
的行项目信息,并且它应该按预期工作。