Recyclerview不会调用任何Adapter方法: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" />
答案 0 :(得分:1)
您正在初始化适配器之前在recyclerview上设置适配器。尝试:
public static String myReverse(String str) {
byte[] bytes = str.getBytes("ASCII");
// memory at full capacity
str = null;
// memory at 1/3 capacity
for (int i = 0; i < bytes.length / 2; i++) {
byte tmp = bytes[i];
bytes[i] = bytes[bytes.length - i - 1];
bytes[bytes.length - i - 1] = tmp;
}
return new String(bytes, "ASCII");
}