Huge gap between cards of recyclerView - android

I have a recylerView to show the images fetched from firebase cloud, However there is a large gap between some items and these gaps arise after i start scrolling, before scrolling, everything is placed perfectly, I have read a few articles, however not proved to be correct in my case.
The code for my MainActivity is given below
RecyclerView.LayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
Query query = firebaseDatabase.getReference().child("Products").child(Uid).orderByKey();
FirebaseRecyclerOptions options = new FirebaseRecyclerOptions.Builder<MainConstructor>().setQuery(query, MainConstructor.class).build();
mFirebaseAdapter = new FirebaseRecyclerAdapter<MainConstructor, ShowDataViewHolder>(options) {
#Override
public ShowDataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_view, parent, false);
return new ShowDataViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull ShowDataViewHolder holder, int position, #NonNull MainConstructor model) {
holder.setImg(getApplicationContext(),model.getImageUrl());
holder.setImageText(model.getImageUrl());
holder.setCode(model.getProductCode());
progressDialog.dismiss();
}
};
recyclerView.setAdapter(mFirebaseAdapter);
}
#Override
protected void onStart() {
super.onStart();
mFirebaseAdapter.startListening();
recyclerView.setAdapter(mFirebaseAdapter);
}
#Override
protected void onStop() {
super.onStop();
mFirebaseAdapter.stopListening();
}
The code for ViewHolder class is given as
public class ShowDataViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView img;
TextView imageText, codeText;
public ShowDataViewHolder(final View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
private void setImg(Context ctx, String img1) {
img = (ImageView) itemView.findViewById(R.id.List_ImageView);
Picasso.with(ctx).load(img1).placeholder(R.drawable.notification).into(img);
// progressDialog.dismiss();
}
private void setImageText(String text){
imageText = (TextView)itemView.findViewById(R.id.textView);
imageText.setText(text);
}
private void setCode(String code){
codeText = (TextView)itemView.findViewById(R.id.Code);
codeText.setText(code);
}
The large unwanted gaps can be clearly seen here:
The list_view layout code is given as:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_margin="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/List_ImageView"
android:padding="2dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView"
android:visibility="invisible"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/Code"
android:visibility="invisible"/>
</LinearLayout>
</android.support.v7.widget.CardView>
I have read someWhere that this problem arises because recyclerView continuously keeps on updating the items, so to correct that we need a ViewHolder class, however i have a viewHolder in my case then also this problem is there,
Can anyone help me with the solution and also with the exact problem why is it happening?
Thanks in advance

Your code is perfect just remove your parent node RelativeLayout which is actually not needed. That is creating issue with match_parent height.
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_margin="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/List_ImageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp" />
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible" />
<TextView
android:id="#+id/Code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible" />
</LinearLayout>
</android.support.v7.widget.CardView>

Change this:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
to this:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">

Related

Two RecyclerView inside the same Scrollview, one does not show content

I'm facing a problem with two RecyclerView inside the same ScrollView (I also tried the same with a NestestScrollView). Inside the ScrollView, I have also some other View objects that form a kind of "header section" of the fragment. Then, I would like to show a horizontal list of RecyclerView, and finally, above the horizontal list, a vertical list of other RecyclerView. However, only the horizontal one is correctly visualized. Even though the Adapter of the vertical one is correctly initialized with some objects, when I run the application, the vertical list is empty. I think it is a problem related to my layout.
This is my .xml file:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
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:id="#+id/profile_coordinator"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".HomeFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp">
<!-- Here I have some other views (ImageView, TextView, etc.) -->
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/active_promos"
android:textStyle="bold"
android:textColor="#color/colorPrimary"
android:textSize="18sp"
android:layout_marginBottom="10sp"/>
<!-- Horizontal List of RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/promo_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:layout_marginBottom="20sp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/news"
android:textStyle="bold"
android:textColor="#color/colorPrimary"
android:textSize="18sp"
android:layout_marginBottom="10sp"/>
<!-- Vertical List of RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/news_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
</ScrollView>
Since the objects to show are the same (but the semantics is different), I'm using the same Adapter class that loads two different xml layout according to the type of object to show.
This is the Adapter.java:
public class NewsAdapter extends RecyclerView.Adapter {
private List<NewsPromotion> newsPromotions;
private boolean promos;
public NewsAdapter(List<NewsPromotion> newsPromotions, boolean promos) {
this.newsPromotions = newsPromotions;
this.promos = promos;
}
public void setData(List<NewsPromotion> newsPromotions){
this.newsPromotions = newsPromotions;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder;
if(promos) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.promo_recyclerview_item,
parent, false);
viewHolder = new PromoViewHolder(mView);
}else {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item_row,
parent, false);
viewHolder = new NewsViewHolder(mView);
}
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
Log.d("Adapter", newsPromotions.get(position).title);
if(promos){
PromoViewHolder viewHolder = (PromoViewHolder) holder;
Picasso.get().load(RestClient.BASE_IMAGE_URL + newsPromotions.get(position).image).into(viewHolder.mImage);
}else {
NewsViewHolder viewHolder = (NewsViewHolder) holder;
Picasso.get().load(RestClient.BASE_IMAGE_URL + newsPromotions.get(position).image).into(viewHolder.mImage);
viewHolder.mTitle.setText(newsPromotions.get(position).title);
viewHolder.mDescription.setText(newsPromotions.get(position).content);
}
}
#Override
public int getItemCount() {
return newsPromotions.size();
}
public class NewsViewHolder extends RecyclerView.ViewHolder {
ImageView mImage;
TextView mTitle;
TextView mDescription;
private NewsViewHolder(View itemView) {
super(itemView);
mImage = itemView.findViewById(R.id.ivImage);
mTitle = itemView.findViewById(R.id.tvTitle);
mDescription = itemView.findViewById(R.id.tvDescription);
}
}
public class PromoViewHolder extends RecyclerView.ViewHolder {
ImageView mImage;
private PromoViewHolder(View itemView) {
super(itemView);
mImage = itemView.findViewById(R.id.ivImage);
}
}
}
And the following is how I initialize the two adapters in the Fragment:
RecyclerView promoRecycleView = activity.findViewById(R.id.promo_recyclerview);
promoAdapter = new NewsAdapter(new ArrayList<NewsPromotion>(), true);
promoRecycleView.setAdapter(promoAdapter);
RecyclerView newsRecycleView = activity.findViewById(R.id.news_recyclerview);
newsAdapter = new NewsAdapter(new ArrayList<NewsPromotion>(), false);
newsRecycleView.setAdapter(newsAdapter);
Finally, this is how I send the object to the adapters:
promoAdapter.setData(promos);
promoAdapter.notifyDataSetChanged();
newsAdapter.setData(news);
newsAdapter.notifyDataSetChanged();
Please post your adapter and item_layout. Because your given layout is working perfectly for me.
No issue with your layout i have run in myAppliaction, some issue in Adapter, please post/paste your activity and adapter code.
If you would check documentation on the RecyclerView, you will see that you need to specify size of the list. There is no wrap content for RecyclerView, because it's dynamic widget. So you would need to align your implementation for something like next.
<?xml version="1.0" encoding="utf-8"?>
<NestedScrollView
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:id="#+id/profile_coordinator"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".HomeFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp">
<!-- Here I have some other views (ImageView, TextView, etc.) -->
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/active_promos"
android:textStyle="bold"
android:textColor="#color/colorPrimary"
android:textSize="18sp"
android:layout_marginBottom="10sp"/>
<!-- Horizontal List of RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/promo_recyclerview"
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:layout_marginBottom="20sp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/news"
android:textStyle="bold"
android:textColor="#color/colorPrimary"
android:textSize="18sp"
android:layout_marginBottom="10sp"/>
<!-- Vertical List of RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/news_recyclerview"
android:layout_width="match_parent"
android:layout_height="500dp" />
</LinearLayout>
</LinearLayout>
</ScrollView>

Horizontal recyclerview inside fragment not scrolling

I want to add horizontal recyclerview at the bottom of fragment. I followed the tutorial and successfully implemented horizontal recyclerview and cardview but after trying all possible answers,horizontal scrolling is not working.
Here is my code :-
XML :-
<RelativeLayout tools:context="com.AlfaCab.Menuactivtiy"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:layout_marginTop="56dp"
android:id="#+id/Mainlayout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#color/BgColor"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentBottom="true"
android:background="#drawable/offer_white_box">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Offers"
android:gravity="center"
android:textSize="18sp"
android:textColor="#color/BlackTextColor"
android:textStyle="bold"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView_offer"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:scrollbars="none"/>
<!-- android:orientation="horizontal"
android:scrollbars="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
/> -->
</LinearLayout>
</RelativeLayout>
Here is my offer_cardview.xml / custom layout for recyclerview :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<!-- <!–Offer Start–>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/offer_white_box">
-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!--Offer Coupon-->
<LinearLayout
android:layout_width="140dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/round_box"
>
<LinearLayout
android:id="#+id/ll_offer_bg"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:background="#drawable/offer_red_box"
android:layout_marginBottom="3dp">
<TextView
android:id="#+id/tv_offer_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Get 30% Cashback"
android:textSize="12sp"
android:textColor="#color/WhiteTextColor"
android:textStyle="bold"
android:layout_gravity="center_vertical"
android:gravity="center"/>
</LinearLayout>
<TextView
android:id="#+id/tv_offer_disc"
android:layout_width="match_parent"
android:layout_height="80dp"
android:text="upto Rs. 300 cashback on Outstation"
android:textSize="10sp"
android:textColor="#color/BlackTextColor"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
</LinearLayout>
<!--Offer Coupon Ends-->
</LinearLayout>
<!--</LinearLayout>-->
<!--Offer Ends-->
</android.support.v7.widget.CardView>
</LinearLayout>
HomeFragment.java :-
//a list to store all the products
List<Offer_Data> offerList;
//the recyclerview
RecyclerView recyclerView;
String appOfferId,appOfferTitle,appOfferDes,status;
In onCreate :-
//getting the recyclerview from xml
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView_offer);
After successfully adding data to offerList :-
//creating recyclerview adapter
Offer_Adapter adapter = new Offer_Adapter(getActivity(), offerList);
//adapter.notifyDataSetChanged();
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();// Notify the adapter
Offer_Adapter.java :- (Recyclervire adapter)
public class Offer_Adapter extends RecyclerView.Adapter<Offer_Adapter.ProductViewHolder> {
int[] myImageList;
//this context we will use to inflate the layout
private Context mCtx;
//we are storing all the products in a list
private List<Offer_Data> offerList;
//getting the context and product list with constructor
public Offer_Adapter(Context mCtx, List<Offer_Data> offerList) {
this.mCtx = mCtx;
this.offerList = offerList;
this.myImageList = new int[]{R.drawable.offer_red_box, R.drawable.offer_megento_box, R.drawable.offer_yellow_box};
}
#Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.offer_cardview, null);
return new ProductViewHolder(view);
}
#Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
//getting the product of the specified position
Offer_Data product = offerList.get(position);
//binding the data with the viewholder views
holder.tv_offer_title.setText(product.getOffer_title());
holder.tv_offer_disc.setText(product.getOffer_disc());
int random_box = getRandom(myImageList);
holder.ll_offer_bg.setBackgroundResource(random_box);
}
public static int getRandom(int[] array) {
int rnd = new Random().nextInt(array.length);
return array[rnd];
}
#Override
public int getItemCount() {
return offerList.size();
}
class ProductViewHolder extends RecyclerView.ViewHolder {
TextView tv_offer_title, tv_offer_disc;
LinearLayout ll_offer_bg;
public ProductViewHolder(View itemView) {
super(itemView);
tv_offer_title = (TextView) itemView.findViewById(R.id.tv_offer_title);
tv_offer_disc = (TextView) itemView.findViewById(R.id.tv_offer_disc);
ll_offer_bg = (LinearLayout)itemView.findViewById(R.id.ll_offer_bg);
}
}
}
Please, help me to make it scroll horizontally.
LinearLayoutManager linearLayoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(linearLayoutManager);
Found the Problem
Change this line
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
to
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
Problem is that , you are passing wrong context to recycler view manager
Should use getActivity() not getContext()
ALso no need to add this line in xml
app:layoutManager="android.support.v7.widget.LinearLayoutManager"

Data failing to display in Firebase Recycler View

I've followed a few different docs to pull together my first Firebase Recycler View:
The two main ones:
Here and here.
I'm using a Message object (included further down) with the Firebase Recycler View. For some reason the data is not displaying. Judging from my log outputs, nothing in the adaptor is being called. Here is the activity code that sits in my onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message_details);
RecyclerView mRecyclerView;
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
Query query = myMessagesRef.child(RoomID)
.orderByKey()
.limitToLast(50);
FirebaseRecyclerOptions<Message> options =
new FirebaseRecyclerOptions.Builder<Message>()
.setQuery(query, Message.class)
.build();
FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Message, ChatHolder>(options) {
#Override
public ChatHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.message for each item
final View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_item, parent, false);
return new ChatHolder(view);
}
#Override
protected void onBindViewHolder(ChatHolder holder, int position, Message model) {
//super.onBindViewHolder(holder, position);
Log.w(TAG, "Some Info on messages 2 " + model.MessageText);
holder.bindChat(model);
}
};
mRecyclerView.setAdapter(adapter);
}
Here is my ViewHolder:
static class ChatHolder extends RecyclerView.ViewHolder{
TextView mtext;
//Context mContext;
public ChatHolder(View v) {
super(v);
mtext = (TextView) v.findViewById(com.example.administrationuser.piclo.R.id.textView13);
}
public void bindChat(Message mess){
mtext.setText(mess.MessageText);
}
}
Here is my Message object that I am passing to both Firebase and the adaptor (the data that I input syncs to Firebase with no issue, and my query to firebase gets the data in correct format):
public static class Message {
public String UserID;
public String UserName;
public String MessageText;
public Message() {} // Needed for Firebase
public Message(String UserID, String UserName, String MessageText) {
this.UserID = UserID;
this.UserName = UserName;
this.MessageText = MessageText;
}
}
Here is my Activity Layout XML (with name: activity_message_details.xml):
(note the recycler view near the bottom):
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.administrationuser.piclo.MessageDetails">
<LinearLayout
android:layout_width="395dp"
android:layout_height="643dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:orientation="vertical"
tools:layout_editor_absoluteY="8dp"
tools:layout_editor_absoluteX="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="150dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<EditText
android:id="#+id/editText3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<Button
android:id="#+id/button9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Button"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:onClick="onClick"/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false"
/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Finally, here is my View layout XML (with name: recycler_item.xml):
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView13"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
</FrameLayout >
There were two things that needed fixing.
1) Adding in the adapter.startListening(); (as mentioned by Elvin No Matter). In my case I added this just below the mRecyclerView.setAdapter(adapter); near the end of my onCreate.
2) Enclosing my View Layout XML in a <android.support.v7.widget.LinearLayoutCompat>. See my new View Holder, with some other irrelevant changes to the buttons:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.LinearLayoutCompat
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:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<TextView
android:id="#+id/textView13"
android:layout_width="285dp"
android:layout_height="24dp"
android:text="TextView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_editor_absoluteX="-6dp" />
<TextView
android:id="#+id/textView14"
android:layout_width="123dp"
android:layout_height="24dp"
android:layout_alignParentTop="true"
android:layout_marginRight="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="#+id/textView13"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="154dp" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.LinearLayoutCompat>
according to readme
The FirestoreRecyclerAdapter uses a snapshot listener to monitor
changes to the Firestore query. To begin listening for data, call the
startListening() method. You may want to call this in your onStart()
method. Make sure you have finished any authentication necessary to
read the data before calling startListening() or your query will fail.
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
and
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}

Separating different Views in Android Studio using RecyclerView and CardView

I am using FirebaseRecyclerViewAdapter with CardView in my application and want to load video on one card and images on another, but I dont know how to separate them. Everytime I add a videoView in CardView layout it gets added on the top of ImageView in same card and also gets repeated in all the RecyclerView. Its like same thing is coming again and again with number of posts I have. I want that VideoView should play video on different post and ImageView shows images on different, I have searched many options but did not find anything useful, please help.
I am using Android Studio
CardView xml file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/CardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.youtube.player.YouTubePlayerView
android:id="#+id/youtube"
android:layout_width="match_parent"
android:layout_height="200dp"/>
<ImageView
android:id="#+id/po_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/ti_cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="18sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/de_cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp" />
<TextView
android:id="#+id/so_cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:textColor="#color/SoColor"/>
</LinearLayout>
</android.support.v7.widget.CardView>
FirebaseRecyclerView Adapter class:
FirebaseRecyclerAdapter <post, postViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<post, postViewHolder>(
post.class,
R.layout.post_row_recycle_home,
postViewHolder.class,
mDatabaseReference
) {
#Override
protected void populateViewHolder(postViewHolder viewHolder, post model, int position) {
viewHolder.setTi(model.getTi());
viewHolder.setde(model.getDe());
}
};
mrecyclerView.setAdapter(firebaseRecyclerAdapter);
}
public static class postViewHolder extends RecyclerViewPager.ViewHolder{
View mView;
public postViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setTi(String ti){
TextView post_ti = (TextView)mView.findViewById(R.id.ti_cardView);
post_ti.setText(ti);
}
public void setde(String de){
TextView post_de = (TextView)mView.findViewById(R.id.de_cardView);
post_de.setText(de);
}
set visibility of both gone at first and then depending on its video url or image url. manipulate Visibility of each view
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/CardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.youtube.player.YouTubePlayerView
android:visibility="gone"
android:id="#+id/youtube"
android:layout_width="match_parent"
android:layout_height="200dp"/>
<ImageView
android:visibility="gone"
android:id="#+id/po_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/ti_cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="18sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/de_cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp" />
<TextView
android:id="#+id/so_cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:textColor="#color/SoColor"/>
</LinearLayout>
</android.support.v7.widget.CardView>
As you are using RecyclerView, don't put the VideoPlayer and the ImageView in the same xml layout, you can create two different layouts and use the getItemViewType() to choose the right layout to inflate.
The questions on how to use differente layouts on the same RecyclerView has been answered here
Sample code:
image_item_layout.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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/CardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:visibility="gone"
android:id="#+id/po_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
<...>
</LinearLayout>
</android.support.v7.widget.CardView>
video_item_layout.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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/CardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.youtube.player.YouTubePlayerView
android:visibility="gone"
android:id="#+id/youtube"
android:layout_width="match_parent"
android:layout_height="
<...>
</LinearLayout>
</android.support.v7.widget.CardView>
On the ImageOrVideoAdapter.java you can use something like:
public class ImageOrVideoAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<ImageOrVideoItem> dataSource;
private final int VIDEO_VIEW = 0;
private final int IMAGE_VIEW = 1;
class VideoItemViewHolder extends RecyclerView.ViewHolder {
// Do your stuff with the video here
public VideoItemViewHolder(View itemView) {
}
}
class ImageItemViewHolder extends RecyclerView.ViewHolder {
// Do your stuff with the image here
public ImageItemViewHolder(View itemView) {
}
}
#Override
public int getItemViewType(int position) {
return dataSource.get(position).isVideoItem() ? VIDEO_VIEW : IMAGE_VIEW;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case VIDEO_VIEW:
return new VideoItemViewHolder(inflater.inflate(R.layout.video_item_layout, parent, false));
case IMAGE_VIEW:
return new ImageItemViewHolder(inflater.inflate(R.layout.image_item_layout, parent, false));
}
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
switch (holder.getItemViewType()) {
case VIDEO_VIEW:
VideoItemViewHolder viewHolder0 = (VideoItemViewHolder) holder;
break;
case IMAGE_VIEW:
ImageItemViewHolder viewHolder2 = (ImageItemViewHolder) holder;
break;
}
}
}
There are many posts all around StackOverflow about handling diferent layouts for the same RecyclerView, look around, you will find them.
EDIT
Take a look on this example using FireBase and see if it can adapted to fit your needs: Here

CardView not showing content eclipse

I am using android.support.v7.widget.CardView to show ImageView with two TextView's in RecyclerView but card view not showing the content(showing only blank white cards) when the screen orientation is vertical, on the other hand it is showing content when orientation is landscape.
When I run the same project from AndroidStudio there is no problem everything works fine.
I don't understand what is problem out there, is there problem with eclipse?
Please see the code below,
PostListFragment
public class PostListFragment extends Fragment implements AppConfig {
private ArrayList<Post> mPostArrayList;
private PostRecyclerAdapter mPostRecyclerAdapter;
private RecyclerView mRecyclerView;
//other declarations
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//removed
}
private void init() {
// Set up RecyclerView
mRecyclerView = (RecyclerView) mRootView
.findViewById(R.id.mPostListRecyclerView);
// Setup layout manager for mPostArrayList and column count
final LinearLayoutManager mLayoutManager = new LinearLayoutManager(
getActivity());
// Control orientation of the mPostArrayList
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mLayoutManager.scrollToPosition(0);
// Attach layout manager
mRecyclerView.setLayoutManager(mLayoutManager);
// Listen to the item touching
mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(
getActivity(),
new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View itemView, int position) {
//some action
}
}));
mPostArrayList = new ArrayList<>();
// Bind adapter to recycler
mPostRecyclerAdapter = new PostRecyclerAdapter(
getActivity(), mPostArrayList);
mRecyclerView.setAdapter(mPostRecyclerAdapter);
}
private void getPosts() {
// Execute async task
new AsyncPosts().execute(mPostURL);
}
public class AsyncPosts extends AsyncTask<Object, String, JSONObject> {
//no problem with this
}
}
Layout used for PostListFragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/mParentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/mPostListContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/mPostListSwipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<android.support.v7.widget.RecyclerView
android:id="#+id/mPostListRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
<!-- removed -->
</LinearLayout>
Here is adapter to set the values,
PostRecyclerAdapter
public class PostRecyclerAdapter extends
RecyclerView.Adapter<PostRecyclerAdapter.SimpleItemViewHolder> {
private Context mContext;
private List<Post> post;
// Provide a suitable constructor (depends on the kind of data store)
public PostRecyclerAdapter(Context context, List<Post> items) {
this.mContext = context;
this.post = items;
}
// Return the size of your data set (invoked by the layout manager)
#Override
public int getItemCount() {
return this.post.size();
}
// Create new items (invoked by the layout manager)
// Usually involves inflating a layout from XML and returning the holder
#Override
public SimpleItemViewHolder onCreateViewHolder(ViewGroup viewGroup,
int viewType) {
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.post_list_item, viewGroup, false);
return new SimpleItemViewHolder(itemView);
}
// Replace the contents of a view (invoked by the layout manager)
// Involves populating data into the item through holder
#Override
public void onBindViewHolder(SimpleItemViewHolder viewHolder, int position) {
Glide.with(mContext).load(post.get(position).IMG_URL)
.placeholder(R.drawable.ic_placeholder).crossFade(1000)
.centerCrop().into(viewHolder.mPostListSmallThumbnail);
viewHolder.mPostListSmallTitle.setText(post.get(position).POST_TITLE);
viewHolder.mPostListSmallContent
.setText(post.get(position).POST_CONTENT);
}
// Provide a reference to the views for each data item
// Provide access to all the views for a data item in a view holder
public final static class SimpleItemViewHolder extends
RecyclerView.ViewHolder {
ImageView mPostListSmallThumbnail;
TextView mPostListSmallTitle, mPostListSmallContent;
public SimpleItemViewHolder(View itemView) {
super(itemView);
mPostListSmallThumbnail = (ImageView) itemView
.findViewById(R.id.mPostListSmallThumbnail);
mPostListSmallTitle = (TextView) itemView
.findViewById(R.id.mPostListSmallTitle);
mPostListSmallContent = (TextView) itemView
.findViewById(R.id.mPostListSmallContent);
}
}
}
post_list_item
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/mPostListSmallCard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foreground="#drawable/card_background"
android:clickable="true"
app:cardCornerRadius="#dimen/blog_card_radius"
app:cardUseCompatPadding="true"
app:contentPadding="#dimen/blog_card_radius">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/mPostListSmallThumbnail"
android:layout_width="#dimen/blog_image_thumb_dim"
android:layout_height="#dimen/blog_image_thumb_dim"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:background="#drawable/ic_placeholder"
android:adjustViewBounds="true"
android:contentDescription="#string/image_thumbnail_placeholder" />
<TextView
android:id="#+id/mPostListSmallTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="#dimen/post_list_margin_left"
android:layout_marginStart="#dimen/post_list_margin_right"
android:layout_toEndOf="#+id/mPostListSmallThumbnail"
android:layout_toRightOf="#+id/mPostListSmallThumbnail"
android:ellipsize="end"
android:lines="2"
android:singleLine="false"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/mPostListSmallContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/mPostListSmallThumbnail"
android:layout_alignEnd="#+id/mPostListSmallTitle"
android:layout_alignLeft="#+id/mPostListSmallTitle"
android:layout_alignRight="#+id/mPostListSmallTitle"
android:layout_alignStart="#+id/mPostListSmallTitle"
android:layout_below="#+id/mPostListSmallTitle"
android:ellipsize="end"
android:lines="3"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
</android.support.v7.widget.CardView>
Here is post_list_item for landscape layout
land/post_list_item
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/mPostListSmallCard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginRight="#dimen/blog_card_margin_landscape"
android:layout_marginLeft="#dimen/blog_card_margin_landscape"
app:cardCornerRadius="#dimen/blog_card_radius"
app:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/mPostListSmallThumbnail"
android:layout_width="#dimen/blog_image_thumb_dim"
android:layout_height="#dimen/blog_image_thumb_dim"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:contentDescription="#string/image_thumbnail_placeholder" />
<TextView
android:id="#+id/mPostListSmallTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="#dimen/post_list_margin_left"
android:layout_marginStart="#dimen/post_list_margin_right"
android:layout_toEndOf="#+id/mPostListSmallThumbnail"
android:layout_toRightOf="#+id/mPostListSmallThumbnail"
android:ellipsize="end"
android:lines="2"
android:singleLine="false"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/mPostListSmallContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/mPostListSmallThumbnail"
android:layout_alignEnd="#+id/mPostListSmallTitle"
android:layout_alignLeft="#+id/mPostListSmallTitle"
android:layout_alignRight="#+id/mPostListSmallTitle"
android:layout_alignStart="#+id/mPostListSmallTitle"
android:layout_below="#+id/mPostListSmallTitle"
android:ellipsize="end"
android:lines="3"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
</android.support.v7.widget.CardView>

Categories

Resources