如何使用RecycleView / Firebase检索数据

时间:2018-11-09 09:24:08

标签: java android firebase firebase-realtime-database android-recyclerview

我的firebase数据库如下:

enter image description here

Firebase json:

我需要在recycleview卡视图中显示这些数据:具有相关名称的日期。

我的问题是:如何在java类中实现这一点。目前我是这样的:

我知道,这些名称应类似于Firebase中的名称,但我需要使用getKey和getValue来完成

public class UserParties {
    public String createAccTime, uuid, party;

    public UserParties() {
    }

    public UserParties(String party, String createAccTime) {
        this.party = party;
        this.createAccTime = createAccTime;

    }


    public String getParty() {
        return party;
    }

    public void setParty(String party) {
        this.party = party;
    }

    public String getCreateAccTime() {
        return createAccTime;
    }

    public void setCreateAccTime(String createAccTime) {
        this.createAccTime = createAccTime;
    }

}

主要活动是:

public class AllUserPartiesListActivity extends AppCompatActivity {
    private static final String TAG = "AllUserPartiesListActivity";

    private RecyclerView UserPartiesList;

   // private ImageView BackButton;

    private DatabaseReference UsersRef, AllUserPartiesRef;

    private FirebaseAuth mAuth;

    String currentUserID;


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_all_horizontal_parties);
       // Log.d(TAG, "onCreate: started.");
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        mAuth = FirebaseAuth.getInstance();
        currentUserID = mAuth.getCurrentUser().getUid();


       // UsersRef = FirebaseDatabase.getInstance().getReference().child("users").
        AllUserPartiesRef = FirebaseDatabase.getInstance().getReference().child("all_user_parties").child(currentUserID);;
      //  BackButton = (ImageView) findViewById(R.id.backArrow);


        //The next code is working on displaying all users posts
        UserPartiesList = (RecyclerView) findViewById(R.id.horizontalRecycleView);
        UserPartiesList.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(AllUserPartiesListActivity.this);
        linearLayoutManager.setReverseLayout(true);
        linearLayoutManager.setStackFromEnd(true);
        UserPartiesList.setLayoutManager(linearLayoutManager);


//        BackButton.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
//                Intent i = new Intent (getApplicationContext(),SearchActivity.class);
//                startActivity(i);
//                finish();
//            }
//        });

        DisplayAllUsersData();
    }


    private void DisplayAllUsersData() {
        Query SortPostsInDecendingOrder = AllUserPartiesRef.orderByKey();

        FirebaseRecyclerAdapter<UserParties, PostsViewHolder> firebaseRecyclerAdapter =  new FirebaseRecyclerAdapter<UserParties, PostsViewHolder>
                        (
                                UserParties.class,
                                R.layout.layout_horizontal_list_item,
                                PostsViewHolder.class,
                                SortPostsInDecendingOrder

                        ) {
                    @Override
                    protected void populateViewHolder(final PostsViewHolder viewHolder, UserParties model, int position) {
                        //final String PostKey = getRef(position).getKey();
                        // final int PostIntKey=position;   //var for store post position to return back the user here. Should be declare only here!!!!!!
                        final String UserKey = getRef(position).getKey();

                        viewHolder.setCreateAccTime(model.getCreateAccTime());
                        viewHolder.setParty(model.getParty());




                    }
                };
        UserPartiesList.setAdapter(firebaseRecyclerAdapter);


    }

    public static class PostsViewHolder extends RecyclerView.ViewHolder {
        View mView;

        public PostsViewHolder(View itemView) {
            super(itemView);
            mView = itemView;

        }



        public void setCreateAccTime(String createTime) {
            TextView CreateTime = (TextView) mView.findViewById(R.id.name);
            CreateTime.setText(createTime);
        }


        public void setParty(String party) {
            ImageView UserPostParty = (ImageView) mView.findViewById(R.id.image_view);
            Picasso.get().load(party).fit().into(UserPostParty);
        }


    }

以下也是相关的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_margin="1dp">

    <android.support.v7.widget.CardView
        android:layout_width="120dp"
        android:layout_height="120dp"
        app:cardCornerRadius="4dp"
        app:cardMaxElevation="2dp"
        app:cardElevation="1dp"
        android:layout_centerInParent="true">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <de.hdodenhof.circleimageview.CircleImageView
                android:layout_width="90dp"
                android:layout_height="90dp"
                android:scaleType="centerCrop"
                android:layout_centerHorizontal="true"
                android:id="@+id/image_view"
                android:src="@drawable/ic_kulanu"
                />

            <TextView
                android:id="@+id/name"
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:text="Canada"
                android:layout_below="@+id/image_view"
                android:layout_centerHorizontal="true"
                android:gravity="center"
                android:layout_marginTop="1dp"
                android:textColor="#000"
                android:layout_marginBottom="1dp"
                android:autoSizeTextType="uniform"
                android:autoSizeMinTextSize="8sp"
                android:autoSizeMaxTextSize="15sp"/>
        </RelativeLayout>




    </android.support.v7.widget.CardView>

</RelativeLayout>

完整错误日志:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.bluesky, PID: 32213
    com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.android.bluesky.Admin.UserParties
        at com.google.android.gms.internal.zg.zzb(Unknown Source:221)
        at com.google.android.gms.internal.zg.zza(Unknown Source:0)
        at com.google.firebase.database.DataSnapshot.getValue(Unknown Source:10)
        at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:22)
        at com.firebase.ui.database.ObservableSnapshotArray.getObject(ObservableSnapshotArray.java:141)
        at com.firebase.ui.database.CachingObservableSnapshotArray.getObject(CachingObservableSnapshotArray.java:40)
        at com.firebase.ui.database.FirebaseRecyclerAdapter.getItem(FirebaseRecyclerAdapter.java:127)
        at com.firebase.ui.database.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:164)
        at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6673)
        at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6714)
        at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5647)
        at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5913)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5752)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5748)
        at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2232)
        at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1559)
        at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1519)
        at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:614)
        at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3812)
        at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3529)
        at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1767)
        at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:356)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
        at android.view.Choreographer.doCallbacks(Choreographer.java:761)
        at android.view.Choreographer.doFrame(Choreographer.java:693)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

1 个答案:

答案 0 :(得分:0)

具有RecyclerView.Adapter的自定义实现的解决方案。

public class AllUserPartiesListActivity extends AppCompatActivity {
    private static final String TAG = "AllUserPartiesListActivity";

    private RecyclerView UserPartiesList;
    private DatabaseReference UsersRef, AllUserPartiesRef;
    private FirebaseAuth mAuth;
    private String currentUserID;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_all_horizontal_parties);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        mAuth = FirebaseAuth.getInstance();
        currentUserID = mAuth.getCurrentUser().getUid();

        // *** You may call your variable AllUserPartiesRef yet you don't target all user parties,
        // *** just one user's parties. This could be renamed to currentUserParties.
        AllUserPartiesRef = FirebaseDatabase.getInstance().getReference().child("all_user_parties").child(currentUserID);;

        //The next code is working on displaying all users posts
        UserPartiesList = (RecyclerView) findViewById(R.id.horizontalRecycleView);
        UserPartiesList.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(AllUserPartiesListActivity.this);
        linearLayoutManager.setReverseLayout(true);
        linearLayoutManager.setStackFromEnd(true);
        UserPartiesList.setLayoutManager(linearLayoutManager);

        DisplayAllUsersData();
    }


    private void DisplayAllUsersData() {

        AllUserPartiesRef.addReValueEventListener(new ValueEventListener(){
          @Override
          public void onDataChange(DataSnapshot snapshot){
            List<String> posts = new ArrayList<>();
            for (DataSnapshot nameSnapshot : snapshot.getChildren()) {
              String name = nameSnapshot.getValue(String.class);
              String date = nameSnapshot.getKey();
              String post = date + " " + name;
              posts.add(post); 
            }

            // *** Reaching this point posts list includes your previously fetched
            // *** data in "date name" format, time to bind this data to the Adapter.
            PostsAdapter adapter = new PostsAdapter(AllUserPartiesListActivity.this);
            UserPartiesList.setAdapter(adapter);

            // *** Adapter created, bind the posts and call notify
            adapter.addPosts(posts);
            adapter.notifyDatasetChanged(); 
          }

          @Override
          public void onCancelled(DatabaseError error){}
        });
    }

    public static class PostsAdapter extends RecyclerView.Adapter<PostsAdapter.PostsViewHolder>{

      private Context context;
      //  This is your fetched data in a form of date+name String
      //  since you have only one textview to display this pair.
      private List<String> posts; 

      public PostsAdapter(Context context) {
          this.context = context;
      }

      public void addPosts(List<String> posts) {
          this.posts = posts;
      }

      @NonNull
      @Override
      public PostsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
          LayoutInflater inflater = LayoutInflater.from(context);
          View itemView = inflater.inflate(R.layout.layout_horizontal_list_item, viewGroup, false);
          return new PostsViewHolder(itemView);
      }

      @Override
      public void onBindViewHolder(@NonNull PostsViewHolder postsViewHolder, int position) {
          if (posts != null && posts.size() > 0) {
              postsViewHolder.bindPost(posts.get(position));
          }
      }

      @Override
      public int getItemCount() {
          if (posts != null && posts.size() > 0) {
              return posts.size();
          }
          return 0;
      }

      public static class PostsViewHolder extends RecyclerView.ViewHolder {
        View mView;
        TextView textView;

    public PostsViewHolder(View itemView) {
          super(itemView);
          mView = itemView;
          textView = (TextView) mView.findViewById(R.id.name);
        }

        public void setCreateAccTime(String createTime) {
          TextView CreateTime = (TextView) mView.findViewById(R.id.name);
          CreateTime.setText(createTime);
        }

        public void setParty(String party) {
          ImageView UserPostParty = (ImageView) mView.findViewById(R.id.image_view);
          Picasso.get().load(party).fit().into(UserPostParty);
        }

        public bindPost(String post){
          textView.setText(post);
        }
      }
    }
}