【问题标题】:Array Adapter is not updating in onDataChange() method阵列适配器未在 onDataChange() 方法中更新
【发布时间】:2018-04-06 06:12:34
【问题描述】:

这是我的 ArrayAdapter:

public class SackViewAdapter extends ArrayAdapter<PostInfo> {
    private ArrayList<PostInfo> postInfo;
    private Context context;
    private LayoutInflater inflater;

    public SackViewAdapter(@NonNull Context context, int resource,ArrayList<PostInfo> postInfo) {
        super (context, resource);
        this.context = context;
        this.postInfo = postInfo;
        inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        Log.e ("Size", String.valueOf (postInfo.size ()));
        return postInfo.size ();
    }

    @Nullable
    @Override
    public PostInfo getItem(int i) {
        return postInfo.get (i);
    }

    @NonNull
    @Override
    public View getView(int i, View view, @NonNull ViewGroup parent) {
        view  = inflater.inflate (R.layout.card_sack_view, parent,false);
        SelectableRoundedImageView imageView = view.findViewById (R.id.image_view);
        TextView name = view.findViewById (R.id.nameCards);
        TextView username = view.findViewById (R.id.usernameCards);
        imageView.setDrawingCacheEnabled (true);
        name.setText (postInfo.get (i).name);
        username.setText (postInfo.get (i).username);
        try{
            Glide.with (context).load (postInfo.get (i).Url).into (imageView);
        }catch (Exception e){
            Toast.makeText (context, e.getMessage (), Toast.LENGTH_SHORT).show ();
        }
        Log.e ("i", String.valueOf (i));
        return view;
    }
}

这是我的主要活动:

public class WallActivity extends AppCompatActivity {

    FloatingActionButton newFloatingButton;
    SackViewAdapter baseAdapter;
    ArrayList<PostInfo> postInfos;
    DatabaseReference reference = FirebaseDatabase.getInstance ().getReference ();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView (R.layout.activity_wall);
        postInfos = new ArrayList<PostInfo> ();
        String isDirectly = getIntent ().getStringExtra ("directly");
        if(isDirectly.equals ("yes")){
            AuthAsyncTask authAsyncTask = new AuthAsyncTask (WallActivity.this);
            authAsyncTask.execute ();
        }
        getData ();
        CardStackView cardStackView = findViewById(R.id.cardView);
        newFloatingButton = findViewById(R.id.newFloatingButton);
        newFloatingButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(WallActivity.this, NewItemActivity.class);
                startActivity(intent);
                overridePendingTransition(R.anim.slide_up, R.anim.slide_down);
            }
        });
        cardStackView.setCardEventListener(new CardStackView.CardEventListener() {
            @Override
            public void onCardDragging(float percentX, float percentY) {

            }

            @Override
            public void onCardSwiped(SwipeDirection direction) {

            }

            @Override
            public void onCardReversed() {

            }

            @Override
            public void onCardMovedToOrigin() {

            }

            @Override
            public void onCardClicked(int index) {
                Toast.makeText(WallActivity.this, "Clicked", Toast.LENGTH_SHORT).show();
            }
        });
        baseAdapter = new SackViewAdapter (WallActivity.this,android.R.layout.simple_list_item_1, postInfos);
        cardStackView.setAdapter(baseAdapter);
    }

    public void getData(){
        reference.addValueEventListener (new ValueEventListener () {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                DataSnapshot posts = dataSnapshot.child ("Posts");
                for (DataSnapshot time: posts.getChildren ()){
                    DataSnapshot url = time.child ("Url");
                    DataSnapshot name = time.child ("Name");
                    DataSnapshot username = time.child ("Username");
                    DataSnapshot date = time.child ("Date");
                    PostInfo postInfo = new PostInfo (String.valueOf (url.getValue ()), String.valueOf (name.getValue ()), String.valueOf (username.getValue ()), String.valueOf (date.getValue ()));
                    postInfos.add (postInfo);
                }
                baseAdapter.notifyDataSetChanged ();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Toast.makeText (WallActivity.this, "Error 411: " + databaseError.getMessage (), Toast.LENGTH_SHORT).show ();
            }
        });
    }
}

当我从 getData() 函数获取所有数据时,我更新了我的数组适配器,但在更新数组列表的实际大小后,结果为 7,但 getView 函数将 i 的值从 0 变为 2只要。它没有添加来自ArrayList 的所有值,而是一次又一次地显示相同的值,而不是显示不同的值。这是屏幕加载时的日志,因为我在getView 中添加了 Log.e:

 04-06 13:04:26.797 10246-10246/lifeline.learn.com.hotornot E/Value of i: 0
04-06 13:04:26.804 10246-10246/lifeline.learn.com.hotornot E/Value of i: 1
04-06 13:04:26.814 10246-10246/lifeline.learn.com.hotornot E/Value of i: 2

它没有超过 2。但是当我登录 getCount 时它返回 7。

【问题讨论】:

  • 检查你的 url 列表大小
  • 发布此方法也 AuthAsyncTask
  • 更好的方法是创建一个对象数组列表,然后将此数组列表传递给您的适配器
  • 从您的代码中,您仅引用 urls ArrayList。如果 urls ArrayList 中只有 2 个值怎么办? (检查适配器中的 getCount())。所以更好的方法就像@Navneetヅ建议的那样。
  • 所有 ArrayList 大小相同。

标签: java android arrays firebase android-arrayadapter


【解决方案1】:

目前,您的 adaptergetCount() 返回 urls.size (); 的大小,但您也传递了其他 2 个数组列表,它们只会占用 urls 数组列表的大小。

如果您传递Arraylist&lt;UserObject&gt;,您可以将所有数据添加到该对象,然后返回大小为userObjects.size();

所以更好的方法是创建一个对象,比如UserObject,然后用这个对象创建一个数组列表,比如Arraylist&lt;UserObject&gt;

UserObject.java

public class UserObject {
String urls;
String names;
String usernames;
String dates;

public UserObject(String urls, String names, String usernames, String dates) {
    this.urls = urls;
    this.names = names;
    this.usernames = usernames;
    this.dates = dates;
}
}

声明一个数组列表

ArrayList<UserObject> userData=new ArrayList<>();

现在,像这样改变

public void onDataChange(DataSnapshot dataSnapshot) {
            DataSnapshot posts = dataSnapshot.child ("Posts");
            for (DataSnapshot time: posts.getChildren ()){
                DataSnapshot url = time.child ("Url");
                DataSnapshot name = time.child ("Name");
                DataSnapshot username = time.child ("Username");
                DataSnapshot date = time.child ("Date");
                UserObject user=new UserObject(String.valueOf (url.getValue ()),String.valueOf (name.getValue ()),String.valueOf (username.getValue ()),String.valueOf (date.getValue ()));
                userData.add(user);
            }
            baseAdapter.notifyDataSetChanged ();
        }

你的适配器构造函数会是这样的

public SackViewAdapter(@NonNull Context context, int resource,ArrayList<UserObject> userObjects)

【讨论】:

  • 这对我没有帮助。
  • 什么没有帮助?您能具体说明您在上述方法中遇到的问题吗
  • 将 ArrayList 更改为 UserObject 没有任何区别。
  • 你使用ArrayList&lt;UserObject&gt;时的尺寸是否相同?,分享代码
  • 更新你使用ArrayList&lt;UserObject&gt;的代码
【解决方案2】:

请不要在getData() 中拨打这些电话 您已经在 onCreate() 上对其进行了初始化,并且每次发生更改时都会调用 addValueEventListener

urls.clear ();
        usernames.clear ();
        dates.clear ();
        times.clear ();

如果你使用自定义对象数组列表而不是使用三个单独的字符串类型列表并管理它们,那会更好

【讨论】:

    【解决方案3】:

    如果它们的大小为 2,请检查您的 url 大小,然后只取 0 到 2。 因为您添加了尺寸的适配器..

    @Override
    public int getCount() {
        return urls.size (); // in that provide large size of your data.
    }
    

    然后在你绑定适配器之后然后在使用之后..

    notifyDataSetChanged ();
    

    【讨论】:

      猜你喜欢
      • 2020-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多