Recyclerview doesnt call any Adapter method :onBindViewHolder,onCreateViewHolder therefor the adapter is empty
here is my code :
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;
}
}
the adapter class
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);
}
}
the main class
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" />
You are setting the adapter on the recyclerview before the adapter has been initialised. Try:
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);
Related
I'm new to the concepts of RecyclerView and Firebase; I'm working on this chat app that takes input from the user (message) and takes the DisplayName(Google sign in, so the Username) and stores it to the realtime database of the Firebase. The storing of the "mAuthor" and "mMessage" is working fine, the problem arises when I'm trying to retrieve the data and display it in the recyclerView. There's no crash error as per the Logcat, however, there's nothing getting displayed on my chat app screen (in the recyclerView).
The dependencies of firebase and recyclerView have been carefully added.
Here's my activity class:
private String mDisplayName;
private EditText mMessage;
private ImageView mSendButton;
private RecyclerView mRecycler;
private DatabaseReference mDatabaseReference;
private MyAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
mMessage=(EditText) findViewById(R.id.messageInput);
mSendButton=(ImageView) findViewById(R.id.sendButton);
setupDisplayName();
mDatabaseReference= FirebaseDatabase.getInstance().getReference();
mRecycler=(RecyclerView) findViewById(R.id.chat_recycler_view);
mRecycler.setHasFixedSize(true);
LinearLayoutManager layoutManager= new LinearLayoutManager(ChatActivity.this);
mRecycler.setLayoutManager(layoutManager);
mMessage.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
sendMessage();
return true;
}
});
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendMessage();
}
});
}
private void setupDisplayName(){
Intent mIntent= getIntent();
String option= mIntent.getStringExtra("Options");
if(option.equals("normal")){
SharedPreferences prefs= getSharedPreferences(RegisterActivity.CHAT_PREFS,0);
mDisplayName=prefs.getString(RegisterActivity.DISPLAY_NAME_KEY,null);
Log.d("Google","Shared prefs: DisplayName:"+mDisplayName);
}
else if(option.equals("google")){
SharedPreferences prefs= getSharedPreferences(MainActivity.CHAT_PREFS,0);
mDisplayName=prefs.getString(MainActivity.DISPLAY_NAME_KEY,null);
Log.d("Google","Shared prefs: DisplayName:"+mDisplayName);
}
if(mDisplayName==null)
mDisplayName="Anonymous";
}
private void sendMessage() {
String input= mMessage.getText().toString();
if(!input.equals("")){
Log.d("Google","I sent something");
InstantMessage mObject= new InstantMessage(mDisplayName, input);
mDatabaseReference.child("messages").push().setValue(mObject);
mMessage.setText("");
}
}
#Override
public void onStart() {
super.onStart();
mAdapter= new MyAdapter(mDatabaseReference, mDisplayName);
mRecycler.setAdapter(mAdapter);
}
#Override
public void onStop(){
super.onStop();
mAdapter.CleanUp();
}
Here's my Model class:
public class InstantMessage {
private String mAuthor;
private String mMessage;
public InstantMessage(String mAuthor, String mMessage) {
this.mAuthor = mAuthor;
this.mMessage = mMessage;
}
public InstantMessage() {
}
public String getmAuthor() {
return mAuthor;
}
public void setmAuthor(String mAuthor) {
this.mAuthor = mAuthor;
}
public void setmMessage(String mMessage) {
this.mMessage = mMessage;
}
public String getmMessage() {
return mMessage;
}
}
Here's my Adapter class:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private DatabaseReference mReference;
private String mDisplayName;
private List<InstantMessage> mList;
private ChildEventListener mListener= new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
InstantMessage msg= dataSnapshot.getValue(InstantMessage.class);
mList.add(msg);
Log.d("Google","Datasnapshot added:"+dataSnapshot.toString());
notifyDataSetChanged();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
public MyAdapter( DatabaseReference mReference, String mDisplayName) {
this.mReference = mReference.child("messages");
mReference.addChildEventListener(mListener);
this.mDisplayName = mDisplayName;
mList= new ArrayList<>();
}
#NonNull
#Override
public MyAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_chat_row, parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyAdapter.ViewHolder holder, int position) {
holder.mAuthorName.setText(mList.get(position).getmAuthor());
holder.mText.setText(mList.get(position).getmMessage());
}
#Override
public int getItemCount() {
Log.d("Google","Item count:"+mList.size());
return mList.size();
}
public void CleanUp(){
mReference.removeEventListener(mListener);
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView mAuthorName;
TextView mText;
public ViewHolder(View itemView) {
super(itemView);
mAuthorName=(TextView) itemView.findViewById(R.id.Chatauthor);
mText= (TextView) itemView.findViewById(R.id.Chatmessage);
}
}
}
I'm not sure what I'm doing wrong. In the log statement of onChildAdded method, the datasnapshot.toString() returns legit values. However, the Log.d("Google","Item Count:"+mList.size()) returns ItemCount: 1 everytime
PS: Here's the data that is being sent to the firebase: https://imageshack.com/a/img922/1458/HoOWxO.png
My activity_chat_row.xml code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/Chatauthor"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_gravity="start"
android:textColor="#3CB371"
android:gravity="center_vertical"
android:textSize="15sp"
android:textStyle="bold"
android:text="Author"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/Chatmessage"
android:layout_gravity="start"
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:padding="10dp"
android:textSize="15sp"
android:text="Text"
android:textColor="#android:color/primary_text_light"
/>
</LinearLayout>
I was testing my app on many device and it was working fine...Untill I tested on an android device running android 7.1 the recycler view is gone while it exists on other devices tahte my Code:
RecyclerGridLayoutAdapter:
public class RecyclerGridLayoutAdapter extends RecyclerView.Adapter<RecyclerGridLayoutAdapter.ViewHolder>{
private int resource;
private ArrayList<Item> contacts;
private TreeMap<String,ArrayList<Contact>> gridsMap;
private String searchedString;
private Context activity;
private String myNumber;
public RecyclerGridLayoutAdapter(int resource, ArrayList<Item> contacts,Context activity) {
this.resource = resource;
this.contacts = contacts;
this.activity=activity;
gridsMap= DatabaseHandler.getDataBaseHandler(activity).getContactsByAlphabets();
loadData();
searchedString="";
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
v= LayoutInflater.from(activity).inflate(resource,parent,false);
ViewHolder vh=new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
Log.wtf("begin ","inserting "+contacts.get(position).type);
if(contacts.get(position).type==0){
holder.header.setVisibility(View.VISIBLE);
holder.header.setText(contacts.get(position).alphabet);
holder.name.setVisibility(View.GONE);
holder.image.setVisibility(View.GONE);
}
else {
holder.header.setVisibility(View.GONE);
holder.name.setVisibility(View.VISIBLE);
holder.image.setVisibility(View.VISIBLE);
SharedPreferences prefs=activity.getSharedPreferences("myNumber",0);
final String myNumber=prefs.getString("number","not pund");
holder.name.setText(contacts.get(position).contact.name);
if(contacts.get(position).contact.isRegistered.equalsIgnoreCase("true")){
holder.image.setBackgroundResource(R.drawable.contact_offline_pic);
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent=new Intent(activity, ChatRoomActivity.class);
AppMasterManager.activity=ChatRoomActivity.class;
intent.putExtra("room",contacts.get(position).contact.room);
intent.putExtra("contact_name",contacts.get(position).contact.name);
intent.putExtra("myNumber",myNumber);
if (contacts.get(position).contact.isPrivate.equalsIgnoreCase("true")){
if (!DatabaseHandler.getDataBaseHandler(activity).numberExist(contacts.get(position).contact.phone_number)){
DatabaseHandler.getDataBaseHandler(activity).addPrivateContact(contacts.get(position).contact);
try {
ChatService.bind.getService().joinANumber(contacts.get(position).contact);
} catch (JSONException e) {
e.printStackTrace();
}
}
intent.putExtra("account", Accounts.SECONDARY_ACCOUNT);
}else {
intent.putExtra("account", Accounts.PRIMARY_ACCOUNT);
}
Log.wtf("from grid adapter inflater",contacts.get(position).contact.room);
activity.startActivity(intent);
}
});
if(contacts.get(position).contact.state.equalsIgnoreCase("offline")){
holder.image.setBackgroundResource(R.drawable.contact_offline_pic);
}
else {
holder.image.setBackgroundResource(R.drawable.contact_online_pic);
}
}
else {
holder.image.setBackgroundResource(R.drawable.contact_unregistered_pic);
}
}
}
#Override
public int getItemCount() {
return contacts.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView header;
public TextView name;
public ImageView image;
public ViewHolder(View itemView) {
super(itemView);
header=(TextView)itemView.findViewById(R.id.first_char_header);
name=(TextView)itemView.findViewById(R.id.contact_name);
image=(ImageView)itemView.findViewById(R.id.image_grid_contact);
}
}
#Override
public int getItemViewType(int position) {
if(contacts.get(position).type==0){
return 4;
}
else {
return 1;
}
}
public void search(String pattern){
searchedString=pattern;
if(!TextUtils.isEmpty(pattern)) {
searchedString=pattern;
gridsMap.clear();
gridsMap=DatabaseHandler.getDataBaseHandler(activity).getContactsByAlphabetsWithPattern(pattern);
contacts.clear();
loadData();
}
else {
gridsMap.clear();
gridsMap=DatabaseHandler.getDataBaseHandler(activity).getContactsByAlphabets();
contacts.clear();
loadData();
}
notifyDataSetChanged();
}
public void updateDataSet(){
if(!TextUtils.isEmpty(searchedString)){
contacts.clear();
gridsMap.clear();
gridsMap=DatabaseHandler.getDataBaseHandler(activity).getContactsByAlphabetsWithPattern(searchedString);
loadData();
notifyDataSetChanged();
}
else {
contacts.clear();
gridsMap.clear();
gridsMap=DatabaseHandler.getDataBaseHandler(activity).getContactsByAlphabets();
loadData();
notifyDataSetChanged();
}
}
void loadData(){
for(String c:gridsMap.keySet()){
contacts.add(new Item(0,c));
Log.wtf("add","+");
for(Contact d:gridsMap.get(c)){
contacts.add(new Item(1,c,d));
}}
}
public void searchOnline(final String pattern) throws JSONException {
if(!TextUtils.isEmpty(pattern)){
JSONObject object=new JSONObject();
object.put("pattern",pattern);
JsonObjectRequest request_json = new JsonObjectRequest(WebServiceApi.SEARCH_SECONDARY_CONTACTS_ONLINE,object, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
if(response.getJSONArray("res").length()>0){
contacts.clear();
Log.w("result ",response.getJSONArray("res").getJSONObject(0).getJSONObject("secondary_account").getString("user_name").toString());
contacts.add(new Item(0,pattern.toCharArray()[0]+""));
for(int i=0;i<response.getJSONArray("res").length();i++){
String name=response.getJSONArray("res").getJSONObject(i).getJSONObject("secondary_account").getString("user_name");
String phone_number=response.getJSONArray("res").getJSONObject(i).getString("phone_number");
String room;
if(phone_number.compareTo(myNumber)>0){
room=phone_number+myNumber;
}
else {
room=myNumber+phone_number;
}
Contact contact=new Contact();
contact.name=name;
contact.room=room;
contact.phone_number=phone_number;
contact.isRegistered="true";
contact.state="offline";
contact.isPrivate="true";
contacts.add(new Item(1,pattern.toCharArray()[0]+"",contact));
}
notifyDataSetChanged();
}
else{
contacts.clear();
loadData();
notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("No Activity", error.getMessage());
}
});
AppController.getInstance().addToRequestQueue(request_json);
}
else {
contacts.clear();
loadData();
notifyDataSetChanged();
}
}
public void setNumber(String number){
myNumber=number;
}
}
ContactsFragement:
public class ContactsFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnContactsFragementInteraction mListener;
private RecyclerView listContacts;
private GridLayoutManager manager;
private HashMap<String,Contact> roomMaps;
private String number;
private boolean isLoaded=false;
private RecyclerGridLayoutAdapter adapter;
public ContactsFragment() {
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment ContactsFragment.
*/
// TODO: Rename and change types and number of parameters
public static ContactsFragment newInstance(String param1, String param2) {
ContactsFragment fragment = new ContactsFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_contacts, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mListener.pressed();
if(savedInstanceState==null){Toast.makeText(getActivity(),"First Time running this fragment",Toast.LENGTH_SHORT).show();}
roomMaps = new HashMap<>();
listContacts = (RecyclerView) getActivity().findViewById(R.id.list_contacts);
EditText contact_search_box = (EditText) getActivity().findViewById(R.id.search_box_contacts);
contact_search_box.clearFocus();
number = this.getArguments().getString("number");
// contactsListAdapter = new ContactsListAdapterAlternative(getActivity(), new ArrayList<GridLayoutAdapter>(), R.layout.list_contacts_item);
// listContacts.setAdapter(contactsListAdapter);
manager=new GridLayoutManager(getActivity(),4);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
return (adapter.getItemViewType(position));
}
});
adapter=new RecyclerGridLayoutAdapter(R.layout.list_contacts_item,new ArrayList<Item>(),getActivity());
adapter.setNumber(number);
manager.setOrientation(LinearLayoutManager.VERTICAL);
listContacts.setLayoutManager(manager);
listContacts.setHasFixedSize(true);
listContacts.setAdapter(adapter);
EditText search_online_box=getActivity().findViewById(R.id.search_online);
search_online_box.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
try {
adapter.searchOnline(s.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
contact_search_box.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
adapter.search(charSequence.toString());
}
#Override
public void afterTextChanged(Editable editable) {
}
});
isLoaded=true;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnContactsFragementInteraction) {
mListener = (OnContactsFragementInteraction) context;
mListener.pressed();
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
public void updateState(String room,HashMap<String,String> map) {
if(adapter!=null)
adapter.updateDataSet();
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* 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>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnContactsFragementInteraction {
// TODO: Update argument type and name
void pressed();
ChatService getService();
void setRoutablity(boolean routablity);
}
}
fragment_contacts:
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/contactsFragment"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal"
android:id="#+id/topSearchBar"
android:weightSum="2">
<EditText
android:id="#+id/search_box_contacts"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:padding="10dp"
android:textSize="15sp"
android:hint="search contacts"
android:background="#beddeb"/>
<EditText
android:id="#+id/search_online"
android:layout_width="0dp"
android:layout_height="match_parent"
android:hint="search online"
android:padding="10dp"
android:textSize="15sp"
android:background="#5fc0e9"
android:layout_weight="1"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/list_contacts"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/topSearchBar"
android:scrollbars="vertical"
tools:listitem="#layout/list_contacts_item">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
list_contact_item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="#+id/first_char_header"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="a"
android:paddingTop="6dp"
android:paddingLeft="8dp"
android:textSize="25sp"
android:textColor="#c1292f"
android:background="#f2f2f2"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:lines="2"
android:id="#+id/contact_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Abdallah"
android:padding="5dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp"
android:src="#drawable/contact_small"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:id="#+id/image_grid_contact"
android:background="#drawable/contact_offline_pic"/>
</LinearLayout>
</LinearLayout>
This gridView is simply a contacts grid where it shows all the contacts available and registered in my network...
On log it shows that it recognizes that there are registered contacts and even it receives a message and if I open the chats tab i see that this listview contact send a message though no contact is appearing in the recycler view...
I'm building a RecyclerView in a Fragment, which brings in data from Firebase database and suppose to show them on a CardView. I wrote all the code as shown below but all that appears upon running is an empty RecyclerView Fragment with the method getItemCount() returning always 0.
card_item.xml
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="10dp"
android:orientation="horizontal"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary">
<TextView
android:id="#+id/primaryText"
android:layout_width="300dp"
android:layout_height="60dp"
android:textColor="#color/colorPrimary"
android:textSize="24sp" />
<TextView
android:id="#+id/subText"
android:layout_width="300dp"
android:layout_height="60dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:textColor="#color/colorPrimary"
android:textSize="14sp" />
<TextView
android:id="#+id/rateValue"
android:layout_width="300dp"
android:layout_height="60dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/subText"
android:textColor="#color/colorPrimary"
android:textSize="24sp" />
</RelativeLayout>
fragment_profile.xml
<LinearLayout 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"
android:background="#F1F1F1"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/placesRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
PlacesModel.java
public class PlaceModel {
private String mPrimaryText, mSubText, mRateValue;
public PlaceModel() {
}
public PlaceModel(String mCardImage, String mPrimaryText,
String mSubText, String mRateValue) {
//this.mCardImageURL = mCardImage;
this.mPrimaryText = mPrimaryText;
this.mSubText = mSubText;
this.mRateValue = mRateValue;
}
public void setmPrimaryText(String mPrimaryText) {
this.mPrimaryText = mPrimaryText;
}
public void setmSubText(String mSubText) {
this.mSubText = mSubText;
}
public void setmRateValue(String mRateValue) {
this.mRateValue = mRateValue;
}
public String getmPrimaryText() {
return mPrimaryText;
}
public String getmSubText() {
return mSubText;
}
public String getmRateValue() {
return mRateValue;
}}
PlacesAdapter.java
public class PlacesAdapter extends RecyclerView.Adapter<PlacesAdapter.PlacesViewHolder> {
private ArrayList<PlaceModel> cardContents;
private Context context;
public PlacesAdapter(Context context, ArrayList<PlaceModel> cardContents) {
this.cardContents = cardContents;
this.context = context;
}
#Override
public PlacesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.card_item, parent, false);
return new PlacesViewHolder(view);
}
#Override
public void onBindViewHolder(PlacesViewHolder holder, int position) {
PlaceModel place = cardContents.get(position);
holder.primaryText.setText(place.getmPrimaryText());
holder.subText.setText(place.getmSubText());
holder.rateValue.setText(place.getmRateValue());
}
#Override
public int getItemCount() {
return cardContents.size();
}
public class PlacesViewHolder extends RecyclerView.ViewHolder {
CardView cardView;
public TextView primaryText, subText, rateValue;
public PlacesViewHolder(View itemView) {
super(itemView);
cardView = (CardView) itemView.findViewById(R.id.cardView);
primaryText = (TextView) itemView.findViewById(R.id.primaryText);
subText = (TextView) itemView.findViewById(R.id.subText);
rateValue = (TextView) itemView.findViewById(R.id.rateValue);
}
}}
FirebaseConnector.java
public class FirebaseConnector {
DatabaseReference db;
PlaceModel placeModel = new PlaceModel();
ArrayList<PlaceModel> cardContent = new ArrayList<>();
public FirebaseConnector(DatabaseReference db) {
this.db = db;
}
public ArrayList<PlaceModel> retrieve() {
db.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return cardContent;
}
private void fetchData(DataSnapshot dataSnapshot) {
cardContent.clear(); //clear card content from last usage
for (DataSnapshot ds : dataSnapshot.getChildren()) {
placeModel = ds.child("Place Model").getValue(PlaceModel.class);
cardContent.add(placeModel);
}
}}
ProfileFragment.java
public class ProfileFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
/////////////////////////////////////////////////////////////
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private RecyclerView placesRecycler;
private PlacesAdapter placesAdapter;
private FirebaseConnector connector;
private DatabaseReference ref;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public ProfileFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static ProfileFragment newInstance(String param1, String param2) {
ProfileFragment fragment = new ProfileFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_profile, container, false);
mAuth = FirebaseAuth.getInstance();
//Initialize Database..
ref = FirebaseDatabase.getInstance().getReference();
connector = new FirebaseConnector(ref);
//Initialize RecyclerView
placesRecycler = (RecyclerView)v.findViewById(R.id.placesRecycler);
placesRecycler.setLayoutManager(new LinearLayoutManager(this.getActivity()));
//Adapter
placesAdapter = new PlacesAdapter(this.getActivity(), connector.retrieve());
placesRecycler.setAdapter(placesAdapter);
Toast.makeText(getActivity(), "We have "+placesAdapter.getItemCount()+" cards", Toast.LENGTH_LONG).show();
return v;
}
#Override
public void onStart() {
super.onStart();
if (mAuth.getCurrentUser() == null) {
startActivity(new Intent(getActivity(), LoginActivity.class));
}
}
public void updateUI() {
if (mAuth.getCurrentUser() == null) {
startActivity(new Intent(getActivity(), LoginActivity.class));
}
}}
Database trial structure
Database trial structure
I see that retrieve method will return empty array list because it won't wait for the listener to finish (note that listener works in another thread)
You may make move the listener to the profile fragment and every time you update the ArrayList write
placesRecycler.notifydatasetchanged();
i am building a simple recycle view with a custom adapter, i already set the position of all of my elements, but somehow the image of my row the main one is not showing up and i don't know why.
Before i changed the xml it was showing up, so basicly i have my main activity:
public class PlantFeed extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener,PlantFeedAdapter.OnItemClickListener {
//initialize fields
String token;
ArrayList<PlantPhotoUser> photos = new ArrayList<>();
VolleyService mVolleyService;
IResult mResultCallback = null;
final String GETREQUEST = "GETCALL";
String connectionTxt;
String URL;
String date;
String lat;
String lon;
String alt;
PlantFeedAdapter plantFeedAdapter;
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plant_feed);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
connectionString connection = ((connectionString) getApplicationContext());
connectionTxt = connection.getGlobalVarValue();
URL = connectionTxt + "/fotos";
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(PlantFeed.this,CameraCapture.class);
startActivity(i);
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
recyclerView = (RecyclerView)findViewById(R.id.recycleView2);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
plantFeedAdapter = new PlantFeedAdapter(getApplicationContext(), photos,PlantFeed.this);
recyclerView.setAdapter(plantFeedAdapter);
token = checkForToken();
initVolleyCallback();
mVolleyService = new VolleyService(mResultCallback,this);
mVolleyService.getDataVolley(GETREQUEST,URL,token);
}
void initVolleyCallback(){
mResultCallback = new IResult() {
#Override
public void notifySuccess(String requestType,JSONObject response) {
Log.d("HELLL","hi1");
}
#Override
public void notifySuccess(String requestType, JSONArray response) {
PlantPhotoUser plantPhotoUser;
Log.d("HELLLL","hi");
for (int i=0; i < response.length(); i++) {
try {
JSONObject object = response.getJSONObject(i);
Log.d("objeto",object.toString());
int userId = object.getInt("userId");
Log.d("objeto",String.valueOf(userId));
String username = object.getJSONObject("user").getString("username");
Log.d("objeto",String.valueOf(username));
int plantId = object.getInt("plantId");
Log.d("objeto",String.valueOf(plantId));
String specie = object.getJSONObject("plant").getString("specie");
Log.d("objeto",String.valueOf(specie));
String path = object.getString("image");
Log.d("objeto",String.valueOf(path));
int fotoId = object.getInt("id");
if(object.getString("date") != null){
date = object.getString("date");
}
if(object.getString("lat") != null){
lat = object.getString("lat");
}
if(object.getString("lon") != null){
lon = object.getString("lon");
}
if(object.getString("altitude") != null){
alt = object.getString("altitude");
}
plantPhotoUser = new PlantPhotoUser(fotoId,plantId,userId,path,specie,date,lat,lon,alt,username);
photos.add(plantPhotoUser);
} catch (JSONException e) {
e.printStackTrace();
}
}
plantFeedAdapter.notifyDataSetChanged();
}
#Override
public void notifyError(String requestType,VolleyError error) {
Log.d("FAIL",error.toString());
}
};
}
public String checkForToken() {
SharedPreferences sharedPref = getSharedPreferences("user", MODE_PRIVATE);
String tokenKey = getResources().getString(R.string.token);
String token = sharedPref.getString(getString(R.string.token), tokenKey); // take the token
return token;
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.plant_feed, 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.Perfil) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
Intent i = new Intent(PlantFeed.this,CameraCapture.class);
startActivity(i);
} else if (id == R.id.nav_gallery) {
Intent i = new Intent(PlantFeed.this,PlantFeed.class);
startActivity(i);
} else if (id == R.id.nav_slideshow) {
Intent i = new Intent(PlantFeed.this,FamilyLibrary.class);
startActivity(i);
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onRowClick(int position, String name, int id, View view) {
}
#Override
public void onTitleClicked(int position, int id, View clickedview) {
Intent i = new Intent(this,PhotosForPlant.class);
i.putExtra("plantId",String.valueOf(id));
startActivity(i);
}
#Override
public void onImageClicked(int position, int id, View clickedview) {
Intent i = new Intent(this,PhotosForPlant.class);
i.putExtra("plantId",String.valueOf(id));
startActivity(i);
}
#Override
public void onReportClicked(int position, int id, String name, View clickedview) {
Log.d("HELLLO","HELLOO");
showDialogReport(id,name);
}
#Override
public void onUserIconClicked(int position, int id, View clickedview) {
Intent i = new Intent(this,UserProfile.class);
i.putExtra("userId",id);
startActivity(i);
}
#Override
public void onUsernameClicked(int position, int id, View clickedview) {
Intent i = new Intent(this,UserProfile.class);
i.putExtra("userId",id);
startActivity(i);
}
#Override
public void onAvaliationClicked(int position, int id, String name, View clickedview) {
}
private void showDialogReport(int id, String name) {
Log.d("HELLLO","HELLOO");
AlertDialog.Builder builder = new AlertDialog.Builder(PlantFeed.this);
builder.setTitle(name);
builder.setMessage("Tem a certeza que pretende reportar a fotografia?");
builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//TODO reportar base de dados
}
});
builder.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
}
and then i have my customer adapter like this:
public class PlantFeedAdapter extends RecyclerView.Adapter<PlantFeedAdapter.ViewHolder> {
private OnItemClickListener listener;
public interface OnItemClickListener {
void onRowClick(int position, String name, int id, View view);
void onTitleClicked(int position, int id, View clickedview);
void onImageClicked(int position,int id, View clickedview);
void onReportClicked(int position, int id,String name, View clickedview);
void onUserIconClicked(int position, int id, View clickedview);
void onUsernameClicked(int position, int id, View clickedview);
void onAvaliationClicked(int position, int id,String name, View clickedview);
}
private ArrayList<PlantPhotoUser> photos;
private Context context;
public PlantFeedAdapter(Context context, ArrayList<PlantPhotoUser> photos, OnItemClickListener listener) {
this.photos = photos;
this.context = context;
this.listener = listener;
}
#Override
public PlantFeedAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.plant_feed_row, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final PlantFeedAdapter.ViewHolder viewHolder, final int i) {
viewHolder.name.setText(photos.get(i).getSpecie());
viewHolder.username.setText(photos.get(i).getUsernName());
viewHolder.data.setText(photos.get(i).getDate().split("T")[0]);
Log.d("data123",(photos.get(i).getDate().toString()));
String urlFoto = "http://fe1b7efd.ngrok.io/" + photos.get(i).getPath();
if(urlFoto.toLowerCase().contains("public/")){
urlFoto = urlFoto.replace("public/","");
}
viewHolder.userIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onUserIconClicked(viewHolder.getAdapterPosition(), photos.get(i).getUserId(), view);
}
}
});
viewHolder.username.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onUsernameClicked(viewHolder.getAdapterPosition(),photos.get(i).getUserId(), view);
}
}
});
viewHolder.plantImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onImageClicked(viewHolder.getAdapterPosition(), photos.get(i).getIdPlant(), view);
}
}
});
viewHolder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
listener.onTitleClicked(viewHolder.getAdapterPosition(),photos.get(i).getIdPlant(),v);
}
}
});
viewHolder.reportImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
listener.onReportClicked(viewHolder.getAdapterPosition(),photos.get(i).getIdPlant(),photos.get(i).getSpecie(),v);
}
}
});
/*viewHolder.avaliationFoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
listener.onAvaliationClicked(viewHolder.getAdapterPosition(),photos.get(i).getIdPlant(),photos.get(i).getSpecie(),v);
}
}
});*/
Picasso.with(context)
.load(urlFoto)
.resize(300, 300)
.into(viewHolder.plantImg);
}
#Override
public int getItemCount() {
return photos.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView name;
private ImageView userIcon;
private TextView avaliationFoto;
private ImageView plantImg;
private ImageView foto;
private TextView username;
private ImageView reportImage;
private TextView data;
public ViewHolder(View view) {
super(view);
data = (TextView)view.findViewById(R.id.data);
name = (TextView) view.findViewById(R.id.plantName);
userIcon = (ImageView)view.findViewById(R.id.userIcon);
plantImg = (ImageView)view.findViewById(R.id.plantPhoto);;
username = (TextView)view.findViewById(R.id.password);
reportImage = (ImageView)view.findViewById(R.id.cameraForbiden);
}
}
}
finally my row xml, wher i think there is the problem
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#cfcfcf">
<LinearLayout
android:layout_margin="10dp"
android:background="#ffffff"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.android.volley.toolbox.NetworkImageView
android:layout_weight="1"
android:layout_width="120dp"
android:layout_height="100dp"
android:padding="0dp"
app:srcCompat="#mipmap/ic_launcher"
android:id="#+id/plantPhoto"
android:background="#c7c7c7"
/>
<LinearLayout
android:layout_weight="20"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/plantName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:padding="15dp"
android:text="TextView"
android:textColor="#000"
android:textSize="20dp" />
<ImageView
android:id="#+id/starIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp"
android:gravity="right"
android:src="#drawable/ic_star" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="15dp">
<com.example.afcosta.inesctec.pt.android.Helpers.NexusBoldTextView
android:id="#+id/data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toStartOf="#+id/cameraForbiden"
android:text="TextView"
android:textColor="#color/base" />
<ImageView
android:id="#+id/cameraForbiden"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:src="#drawable/ic_no_photos" />
<ImageView
android:id="#+id/userIcon"
android:layout_width="15dp"
android:layout_height="15dp"
android:gravity="left"
android:layout_alignParentBottom="true"
android:src="#drawable/ic_user" />
<com.example.afcosta.inesctec.pt.android.Helpers.NexusBoldTextView
android:id="#+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/userIcon"
android:text="Filipe"
android:textColor="#color/base" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
the problem is on this element:
<com.android.volley.toolbox.NetworkImageView
android:layout_weight="1"
android:layout_width="120dp"
android:layout_height="100dp"
android:padding="0dp"
app:srcCompat="#mipmap/ic_launcher"
android:id="#+id/plantPhoto"
android:background="#c7c7c7"
/>
Add centerCrop() with Picasso
Picasso.with(context)
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView)
Change this lines in Your Adapter and in ViewHolder because type cast is wrong. :
private ImageView plantImg;
plantImg = (ImageView)view.findViewById(R.id.plantPhoto);;
to
private NetworkImageView plantImg;
plantImg= (NetworkImageView) findViewById(R.id
.plantPhoto); then set image .
Edit
`private ImageLoader mImageLoader;
mImageLoader = CustomVolleyRequestQueue.getInstance(this.getApplicationContext())
.getImageLoader();
mImageLoader.get(url, ImageLoader.getImageListener(mNetworkImageView,
R.mipmap.truiton_short, android.R.drawable
.ic_dialog_alert));
mNetworkImageView.setImageUrl(url, mImageLoader);`
use this link http://www.truiton.com/2015/03/android-volley-imageloader-networkimageview-example/ for further guide.
I'm using this code to call a CameraFragment using this library https://github.com/florent37/CameraFragment
Here is the MyCameraFragment.java code :
public class MyCameraFragment extends Fragment {
public static final String FRAGMENT_TAG = "camera";
private static final int REQUEST_CAMERA_PERMISSIONS = 931;
#Bind(R.id.action_settings)
CameraSettingsView settingsView;
#Bind(R.id.flash_switch_view)
FlashSwitchView flashSwitchView;
#Bind(R.id.front_back_camera_switcher)
CameraSwitchView cameraSwitchView;
#Bind(R.id.record_button)
RecordButton recordButton;
#Bind(R.id.cameraLayout)
View cameraLayout;
private FragmentActivity myContext;
public MyCameraFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
* #return A new instance of fragment MyCameraFragment.
*/
public static MyCameraFragment newInstance() {
MyCameraFragment fragment = new MyCameraFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String[] permissions = {
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE};
final List<String> permissionsToRequest = new ArrayList<>();
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(getActivity(), permission) != PackageManager.PERMISSION_GRANTED) {
permissionsToRequest.add(permission);
}
}
if (!permissionsToRequest.isEmpty()) {
ActivityCompat.requestPermissions(getActivity(), permissionsToRequest.toArray(new String[permissionsToRequest.size()]), REQUEST_CAMERA_PERMISSIONS);
} else addCamera();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_camera, container, false);
ButterKnife.bind(getActivity(),view);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#OnClick(R.id.flash_switch_view)
public void onFlashSwitcClicked() {
final CameraFragmentApi cameraFragment = getCameraFragment();
if (cameraFragment != null) {
cameraFragment.toggleFlashMode();
}
}
#OnClick(R.id.front_back_camera_switcher)
public void onSwitchCameraClicked() {
final CameraFragmentApi cameraFragment = getCameraFragment();
if (cameraFragment != null) {
cameraFragment.switchCameraTypeFrontBack();
}
}
#OnClick(R.id.record_button)
public void onRecordButtonClicked() {
final CameraFragmentApi cameraFragment = getCameraFragment();
if (cameraFragment != null) {
cameraFragment.takePhotoOrCaptureVideo(new CameraFragmentResultListener() {
#Override
public void onVideoRecorded(String filePath) {
}
#Override
public void onPhotoTaken(byte[] bytes, String filePath) {
Toast.makeText(getActivity(), "onPhotoTaken " + filePath, Toast.LENGTH_SHORT).show();
}
},
"/storage/self/primary",
"photo");
}
}
#OnClick(R.id.settings_view)
public void onSettingsClicked() {
final CameraFragmentApi cameraFragment = getCameraFragment();
if (cameraFragment != null) {
cameraFragment.openSettingDialog();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length != 0) {
addCamera();
}
}
public void addCamera() {
final CameraFragment cameraFragment = CameraFragment.newInstance(new Configuration.Builder()
.setCamera(Configuration.CAMERA_FACE_REAR).build());
getFragmentManager().beginTransaction()
.replace(R.id.content, cameraFragment,FRAGMENT_TAG)
.commitAllowingStateLoss();
if (cameraFragment != null) {
cameraFragment.setStateListener(new CameraFragmentStateListener() {
#Override
public void onCurrentCameraBack() {
cameraSwitchView.displayBackCamera();
}
#Override
public void onCurrentCameraFront() {
cameraSwitchView.displayFrontCamera();
}
#Override
public void onFlashAuto() {
flashSwitchView.displayFlashAuto();
}
#Override
public void onFlashOn() {
flashSwitchView.displayFlashOn();
}
#Override
public void onFlashOff() {
flashSwitchView.displayFlashOff();
}
#Override
public void onCameraSetupForPhoto() {
recordButton.displayPhotoState();
flashSwitchView.setVisibility(View.VISIBLE);
}
#Override
public void onCameraSetupForVideo() {
}
#Override
public void onRecordStateVideoReadyForRecord() {
}
#Override
public void onRecordStateVideoInProgress() {
}
#Override
public void shouldRotateControls(int degrees) {
ViewCompat.setRotation(cameraSwitchView, degrees);
ViewCompat.setRotation(flashSwitchView, degrees);
}
#Override
public void onStartVideoRecord(File outputFile) {
}
#Override
public void onRecordStatePhoto() {
recordButton.displayPhotoState();
}
#Override
public void onStopVideoRecord() {
settingsView.setVisibility(View.VISIBLE);
}
});
cameraFragment.setControlsListener(new CameraFragmentControlsListener() {
#Override
public void lockControls() {
cameraSwitchView.setEnabled(false);
recordButton.setEnabled(false);
settingsView.setEnabled(false);
flashSwitchView.setEnabled(false);
}
#Override
public void unLockControls() {
cameraSwitchView.setEnabled(true);
recordButton.setEnabled(true);
settingsView.setEnabled(true);
flashSwitchView.setEnabled(true);
}
#Override
public void allowCameraSwitching(boolean allow) {
cameraSwitchView.setVisibility(allow ? View.VISIBLE : View.GONE);
}
#Override
public void allowRecord(boolean allow) {
recordButton.setEnabled(allow);
}
#Override
public void setMediaActionSwitchVisible(boolean visible) {
}
});
}
}
private CameraFragmentApi getCameraFragment() {
return (CameraFragmentApi) getFragmentManager().findFragmentByTag(FRAGMENT_TAG);
}
}
Here is fragment_camera.xml Code :
<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="com.team31.plantdetection.fragments.MyCameraFragment">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<RelativeLayout
android:id="#+id/cameraLayout"
android:visibility="visible"
tools:visibility="visible"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:paddingTop="10dp">
<com.github.florent37.camerafragment.widgets.CameraSettingsView
android:id="#+id/settings_view"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
/>
<com.github.florent37.camerafragment.widgets.FlashSwitchView
android:id="#+id/flash_switch_view"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerInParent="true" />
<com.github.florent37.camerafragment.widgets.CameraSwitchView
android:id="#+id/front_back_camera_switcher"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
/>
</RelativeLayout>
<!--android:background="#82000000"-->
<RelativeLayout
android:id="#+id/record_panel"
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="#android:color/transparent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<com.github.florent37.camerafragment.widgets.RecordButton
android:id="#+id/record_button"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_centerInParent="true"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp" />
</RelativeLayout>
</RelativeLayout>
The app crush on launching with the problem : Attempt to ## Heading ##invoke virtual method 'void com.github.florent37.camerafragment.widgets.FlashSwitchView.displayFlashAuto()' on a null object reference
See the Doc
in gradle:
compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
in code:
use ButterKnife.bind(this, view); instead of ButterKnife.bind(getActivity(),view);
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
ButterKnife.bind(this, view);
// TODO Use fields...
return view;
}
EDIT
use #BindView(R.id.button1) Button button1;
As an alternative to this answer, bear in mind that onCreate is called before onCreateView.
If you have code before the ButterKnife is bound it will obviously be null, I ran into issues as I didn't bother looking up the lifecycle when converting an Activity.