1

Recyclerview оленья кожа вызвать любой метод адаптера: onBindViewHolder, onCreateViewHolder для этого адаптера пустRecyclerview оленья кожа вызвать любой метод адаптера: onBindViewHolder, onCreateViewHolder

вот мой код:

public class PostsFragment extends Fragment { 

public static final String TAG = "PostsFragment"; 
private static final String KEY_LAYOUT_POSITION = "layoutPosition"; 
private static final String KEY_TYPE = "type"; 
public static final int TYPE_HOME = 1001; 
public static final int TYPE_FEED = 1002; 
private int mRecyclerViewPosition = 0; 
private OnPostSelectedListener mListener; 


private RecyclerView mRecyclerView; 
private RecyclerView.Adapter<PostViewHolder> mAdapter; 

public PostsFragment() { 
    // Required empty public constructor 
} 

public static PostsFragment newInstance(int type) { 
    PostsFragment fragment = new PostsFragment(); 
    Bundle args = new Bundle(); 
    args.putInt(KEY_TYPE, type); 
    fragment.setArguments(args); 
    return fragment; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View rootView = inflater.inflate(R.layout.fragment_posts, container, false); 
    rootView.setTag(TAG); 

    mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view); 
    return rootView; 
} 

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()); 
    linearLayoutManager.setReverseLayout(true); 
    linearLayoutManager.setStackFromEnd(true); 
    mRecyclerView.setLayoutManager(linearLayoutManager); 

    if (savedInstanceState != null) { 
     // Restore saved layout manager type. 
     mRecyclerViewPosition = (int) savedInstanceState 
       .getSerializable(KEY_LAYOUT_POSITION); 
     mRecyclerView.scrollToPosition(mRecyclerViewPosition); 
     // TODO: RecyclerView only restores position properly for some tabs. 
    } 

    switch (getArguments().getInt(KEY_TYPE)) { 

     case TYPE_HOME: 
      Log.d(TAG, "Restoring recycler view position (following): " + mRecyclerViewPosition); 

      FirebaseUtil.getCurrentUserRef().child("following").addChildEventListener(new ChildEventListener() { 
       @Override 
       public void onChildAdded(final DataSnapshot followedUserSnapshot, String s) { 
        String followedUserId = followedUserSnapshot.getKey(); 
        String lastKey = ""; 
        if (followedUserSnapshot.getValue() instanceof String) { 
         lastKey = followedUserSnapshot.getValue().toString(); 
        } 
        Log.d(TAG, "followed user id: " + followedUserId); 
        Log.d(TAG, "last key: " + lastKey); 
        FirebaseUtil.getPeopleRef().child(followedUserId).child("posts") 
          .orderByKey().startAt(lastKey).addChildEventListener(new ChildEventListener() { 
         @Override 
         public void onChildAdded(final DataSnapshot postSnapshot, String s) { 
          HashMap<String, Object> addedPost = new HashMap<String, Object>(); 
          addedPost.put(postSnapshot.getKey(), true); 
          FirebaseUtil.getFeedRef().child(FirebaseUtil.getCurrentUserId()) 
            .updateChildren(addedPost).addOnSuccessListener(new OnSuccessListener<Void>() { 
           @Override 
           public void onSuccess(Void aVoid) { 
            FirebaseUtil.getCurrentUserRef().child("following") 
              .child(followedUserSnapshot.getKey()) 
              .setValue(postSnapshot.getKey()); 
           } 
          }); 
         } 

         @Override 
         public void onChildChanged(DataSnapshot dataSnapshot, String s) { 

         } 

         @Override 
         public void onChildRemoved(DataSnapshot dataSnapshot) { 

         } 

         @Override 
         public void onChildMoved(DataSnapshot dataSnapshot, String s) { 

         } 

         @Override 
         public void onCancelled(DatabaseError databaseError) { 

         } 
        }); 
       } 

       @Override 
       public void onChildChanged(DataSnapshot dataSnapshot, String s) { 

       } 

       @Override 
       public void onChildRemoved(DataSnapshot dataSnapshot) { 

       } 

       @Override 
       public void onChildMoved(DataSnapshot dataSnapshot, String s) { 

       } 

       @Override 
       public void onCancelled(DatabaseError databaseError) { 

       } 
      }); 

      FirebaseUtil.getFeedRef().child(FirebaseUtil.getCurrentUserId()) 
        .addListenerForSingleValueEvent(new ValueEventListener() { 
         @Override 
         public void onDataChange(DataSnapshot dataSnapshot) { 
          final List<String> postPaths = new ArrayList<>(); 
          for (DataSnapshot snapshot : dataSnapshot.getChildren()) { 
           Log.d(TAG, "adding post key: " + snapshot.getKey()); 
           postPaths.add(snapshot.getKey()); 
          } 
          mAdapter = new FirebasePostQueryAdapter(postPaths, 
            new FirebasePostQueryAdapter.OnSetupViewListener() { 
           @Override 
           public void onSetupView(PostViewHolder holder, Post post, int position, String postKey) { 
            setupPost(holder, post, position, postKey); 
           } 
          }); 
         } 
         @Override 
         public void onCancelled(DatabaseError firebaseError) { 

         } 
        }); 
      break; 
     default: 
      throw new RuntimeException("Illegal post fragment type specified."); 
    } 
    mRecyclerView.setAdapter(mAdapter); 
} 

private FirebaseRecyclerAdapter<Post, PostViewHolder> getFirebaseRecyclerAdapter(Query query) { 
    return new FirebaseRecyclerAdapter<Post, PostViewHolder>(
      Post.class, R.layout.post_item, PostViewHolder.class, query) { 
     @Override 
     public void populateViewHolder(final PostViewHolder postViewHolder, 
             final Post post, final int position) { 
      setupPost(postViewHolder, post, position, null); 
     } 

     @Override 
     public void onViewRecycled(PostViewHolder holder) { 
      super.onViewRecycled(holder); 

     } 
    }; 
} 

private void setupPost(final PostViewHolder postViewHolder, final Post post, final int position, final String inPostKey) { 
    postViewHolder.setPhoto(post.getThumb_url()); 
    postViewHolder.setText(post.getText()); 
    postViewHolder.setTimestamp(DateUtils.getRelativeTimeSpanString(
      (long) post.getTimestamp()).toString()); 
    final String postKey; 
    if (mAdapter instanceof FirebaseRecyclerAdapter) { 
     postKey = ((FirebaseRecyclerAdapter) mAdapter).getRef(position).getKey(); 
    } else { 
     postKey = inPostKey; 
    } 

    Author author = post.getAuthor(); 
    postViewHolder.setAuthor(author.getFull_name(), author.getUid()); 
    postViewHolder.setIcon(author.getProfile_picture(), author.getUid()); 

    ValueEventListener likeListener = new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      postViewHolder.setNumLikes(dataSnapshot.getChildrenCount()); 
      if (dataSnapshot.hasChild(FirebaseUtil.getCurrentUserId())) { 
       postViewHolder.setLikeStatus(PostViewHolder.LikeStatus.LIKED, getActivity()); 
      } else { 
       postViewHolder.setLikeStatus(PostViewHolder.LikeStatus.NOT_LIKED, getActivity()); 
      } 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }; 
    FirebaseUtil.getLikesRef().child(postKey).addValueEventListener(likeListener); 
    postViewHolder.mLikeListener = likeListener; 

    postViewHolder.setPostClickListener(new PostViewHolder.PostClickListener() { 
     @Override 
     public void showComments() { 
      Log.d(TAG, "Comment position: " + position); 
      mListener.onPostComment(postKey); 
     } 

     @Override 
     public void toggleLike() { 
      Log.d(TAG, "Like position: " + position); 
      mListener.onPostLike(postKey); 
     } 
    }); 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    if (mAdapter != null && mAdapter instanceof FirebaseRecyclerAdapter) { 
     ((FirebaseRecyclerAdapter) mAdapter).cleanup(); 
    } 
} 


@Override 
public void onSaveInstanceState(Bundle savedInstanceState) { 
    // Save currently selected layout manager. 
    int recyclerViewScrollPosition = getRecyclerViewScrollPosition(); 
    Log.d(TAG, "Recycler view scroll position: " + recyclerViewScrollPosition); 
    savedInstanceState.putSerializable(KEY_LAYOUT_POSITION, recyclerViewScrollPosition); 
    super.onSaveInstanceState(savedInstanceState); 
} 

private int getRecyclerViewScrollPosition() { 
    int scrollPosition = 0; 
    // TODO: Is null check necessary? 
    if (mRecyclerView != null && mRecyclerView.getLayoutManager() != null) { 
     scrollPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager()) 
       .findFirstCompletelyVisibleItemPosition(); 
    } 
    return scrollPosition; 
} 
/** 
* This interface must be implemented by activities that contain this 
* fragment to allow an interaction in this fragment to be communicated 
* to the activity and potentially other fragments contained in that 
* activity. 
* <p/> 
*/ 
public interface OnPostSelectedListener { 
    void onPostComment(String postKey); 
    void onPostLike(String postKey); 
} 

@Override 
public void onAttach(Context context) { 
    super.onAttach(context); 
    if (context instanceof OnPostSelectedListener) { 
     mListener = (OnPostSelectedListener) context; 
    } else { 
     throw new RuntimeException(context.toString() 
       + " must implement OnPostSelectedListener"); 
    } 
} 

@Override 
public void onDetach() { 
    super.onDetach(); 
    mListener = null; 
} 

}

класс адаптера

public class FirebasePostQueryAdapter extends RecyclerView.Adapter<PostViewHolder> { 
private final String TAG = "PostQueryAdapter"; 
private List<String> mPostPaths; 
private OnSetupViewListener mOnSetupViewListener; 

public FirebasePostQueryAdapter(List<String> paths, OnSetupViewListener onSetupViewListener) { 
    if (paths == null || paths.isEmpty()) { 
     mPostPaths = new ArrayList<>(); 
    } else { 
     mPostPaths = paths; 
    } 
    mOnSetupViewListener = onSetupViewListener; 
} 

@Override 
public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    // create a new view 
    View v = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.post_item, parent, false); 
    return new PostViewHolder(v); 
} 

public void setPaths(List<String> postPaths) { 
    mPostPaths = postPaths; 
    notifyDataSetChanged(); 
} 

public void addItem(String path) { 
    mPostPaths.add(path); 
    notifyItemInserted(mPostPaths.size()); 
} 

@Override 
public void onBindViewHolder(final PostViewHolder holder, int position) { 
    DatabaseReference ref = FirebaseUtil.getPostsRef().child(mPostPaths.get(position)); 
    // TODO: Fix this so async event won't bind the wrong view post recycle. 
    ValueEventListener postListener = new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      Post post = dataSnapshot.getValue(Post.class); 
      Log.d(TAG, "post key: " + dataSnapshot.getKey()); 
      mOnSetupViewListener.onSetupView(holder, post, holder.getAdapterPosition(), 
        dataSnapshot.getKey()); 
     } 

     @Override 
     public void onCancelled(DatabaseError firebaseError) { 
      Log.e(TAG, "Error occurred: " + firebaseError.getMessage()); 
     } 
    }; 
    ref.addValueEventListener(postListener); 
    holder.mPostRef = ref; 
    holder.mPostListener = postListener; 
} 

@Override 
public void onViewRecycled(PostViewHolder holder) { 
    super.onViewRecycled(holder); 
    holder.mPostRef.removeEventListener(holder.mPostListener); 
} 

@Override 
public int getItemCount() { 
    return mPostPaths.size(); 
} 

public interface OnSetupViewListener { 
    void onSetupView(PostViewHolder holder, Post post, int position, String postKey); 
} 

основной класс

public class FeedsActivity extends AppCompatActivity implements PostsFragment.OnPostSelectedListener { 
private static final String TAG = "FeedsActivity"; 
private FloatingActionButton mFab; 

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

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    ViewPager viewPager = (ViewPager) findViewById(R.id.feeds_view_pager); 
    FeedsPagerAdapter adapter = new FeedsPagerAdapter(getSupportFragmentManager()); 
    adapter.addFragment(PostsFragment.newInstance(PostsFragment.TYPE_HOME), "HOME"); 
    adapter.addFragment(PostsFragment.newInstance(PostsFragment.TYPE_FEED), "FEED"); 
    viewPager.setAdapter(adapter); 
    viewPager.setCurrentItem(1); 
    TabLayout tabLayout = (TabLayout) findViewById(R.id.feeds_tab_layout); 
    tabLayout.setupWithViewPager(viewPager); 

    mFab = (FloatingActionButton) findViewById(R.id.fab); 
    mFab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); 
      if (user == null || user.isAnonymous()) { 
       Toast.makeText(FeedsActivity.this, "You must sign-in to post.", Toast.LENGTH_SHORT).show(); 
       return; 
      } 
      Intent newPostIntent = new Intent(FeedsActivity.this, NewPostActivity.class); 
      startActivity(newPostIntent); 
     } 
    }); 
} 

@Override 
public void onPostComment(String postKey) { 
    Intent intent = new Intent(this, CommentsActivity.class); 
    intent.putExtra(CommentsActivity.POST_KEY_EXTRA, postKey); 
    startActivity(intent); 
} 

@Override 
public void onPostLike(final String postKey) { 
    final String userKey = FirebaseUtil.getCurrentUserId(); 
    final DatabaseReference postLikesRef = FirebaseUtil.getLikesRef(); 
    postLikesRef.child(postKey).child(userKey).addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      if (dataSnapshot.exists()) { 
       // User already liked this post, so we toggle like off. 
       postLikesRef.child(postKey).child(userKey).removeValue(); 
      } else { 
       postLikesRef.child(postKey).child(userKey).setValue(ServerValue.TIMESTAMP); 
      } 
     } 

     @Override 
     public void onCancelled(DatabaseError firebaseError) { 

     } 
    }); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_feeds, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
     // TODO: Add settings screen. 
     return true; 
    } else if (id == R.id.action_profile) { 
     startActivity(new Intent(this, ProfileActivity.class)); 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 

class FeedsPagerAdapter extends FragmentPagerAdapter { 
    private final List<Fragment> mFragmentList = new ArrayList<>(); 
    private final List<String> mFragmentTitleList = new ArrayList<>(); 

    public FeedsPagerAdapter(FragmentManager manager) { 
     super(manager); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return mFragmentList.get(position); 
    } 

    @Override 
    public int getCount() { 
     return mFragmentList.size(); 
    } 

    public void addFragment(Fragment fragment, String title) { 
     mFragmentList.add(fragment); 
     mFragmentTitleList.add(title); 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return mFragmentTitleList.get(position); 
    } 
} 

}

activity_feeds.xml

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/main_content" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:fitsSystemWindows="true" 
> 

<android.support.design.widget.AppBarLayout 
    android:id="@+id/appbar" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="?attr/actionBarSize" 
     android:background="?attr/colorPrimary" 
     app:layout_scrollFlags="scroll|enterAlways|snap" 
     app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

    <android.support.design.widget.TabLayout 
     android:id="@+id/feeds_tab_layout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

</android.support.design.widget.AppBarLayout> 

<android.support.v4.view.ViewPager 
    android:id="@+id/feeds_view_pager" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    app:layout_behavior="@string/appbar_scrolling_view_behavior" 
    /> 

<android.support.design.widget.FloatingActionButton 
    android:id="@+id/fab" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="end|bottom" 
    android:layout_margin="@dimen/fab_margin" 
    android:src="@android:drawable/ic_input_add" 
    android:tint="@android:color/white"/> 

post_item.xml

<android.support.v7.widget.CardView 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_margin="8dp" 
android:layout_height="wrap_content" > 


<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 
<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="50dp" 
    android:padding="10dp"> 
    <de.hdodenhof.circleimageview.CircleImageView 
     android:id="@+id/post_author_icon" 
     android:layout_width="@dimen/post_author_icon_size" 
     android:layout_height="@dimen/post_author_icon_size" 
     android:layout_centerVertical="true" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true"/> 
    <TextView 
     android:id="@+id/post_author_name" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerVertical="true" 
     android:layout_toRightOf="@id/post_author_icon" 
     android:layout_marginLeft="4dp" 
     style="@style/Base.TextAppearance.AppCompat.Title" 
     android:textColor="@android:color/primary_text_light_nodisable" 
     android:text="Unknown"/> 
    <TextView 
     android:id="@+id/post_timestamp" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerVertical="true" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentEnd="true" 
     android:layout_gravity="end" 
     android:textColor="@android:color/primary_text_light" 
     android:textSize="18sp" /> 
</RelativeLayout> 
<ImageView 
    android:id="@+id/post_photo" 
    android:layout_width="match_parent" 
    android:layout_height="200dp" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentTop="true" 
    android:scaleType="centerCrop" /> 
    <TextView 
     android:id="@+id/post_text" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:singleLine="false" 
     android:layout_marginLeft="6dp" 
     android:layout_marginRight="6dp" 
     android:layout_marginTop="6dp" 
     android:layout_marginBottom="6dp" 
     android:textColor="@android:color/primary_text_light" 
     android:textSize="16sp" 
     android:ellipsize="end" /> 
    <TextView 
     android:id="@+id/post_num_likes" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="6dp" 
     android:layout_marginRight="6dp" 
     android:layout_marginTop="6dp" 
     android:layout_marginBottom="6dp" 
     android:textColor="@android:color/secondary_text_light" 
     android:textSize="14sp" /> 
    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:padding="6dp"> 
     <ImageView 
      android:id="@+id/post_like_icon" 
      android:layout_width="30dp" 
      android:layout_height="30dp" 
      android:src="@drawable/heart_full"/> 
     <ImageView 
      android:id="@+id/post_comment_icon" 
      android:layout_width="30dp" 
      android:layout_height="30dp" 
      android:layout_marginLeft="6dp" 
      android:layout_toRightOf="@id/post_like_icon" 
      android:src="@drawable/ic_chat_24dp" 
      android:tint="@color/blue_grey_500"/> 
    </RelativeLayout> 

</LinearLayout> 

fragment_posts.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context=".PostsFragment"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/my_recycler_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:scrollbars="vertical" /> 

+2

Просьба ознакомиться с тем, как предоставить [mcve] в ваших вопросах. –

ответ

1

Вы настраиваете адаптер на recyclerview перед адаптер инициализирован. Попытайтесь:

mAdapter = new FirebasePostQueryAdapter(postPaths, 
            new FirebasePostQueryAdapter.OnSetupViewListener() { 
           @Override 
           public void onSetupView(PostViewHolder holder, Post post, int position, String postKey) { 
            setupPost(holder, post, position, postKey); 
           } 
          }); 
mRecyclerView.setAdapter(mAdapter); 
+0

, но это именно то, что я сделал, и его не работает – user3648996

+0

нет, это не то, что вы сделали. вы устанавливаете адаптер вне обратного вызова firebase. обратный вызов firebase вызывается после вызова setAdapter. – sebastian

+0

Поблагодарите так много, это сработало, не могли бы вы объяснить, почему обратный вызов firebase вызывается после вызова setAdapter, хотя вызов setAdapter записывается после переключения, в котором содержится обратный вызов firebase. – user3648996