I have no idea why my cards appear grey on my API 21 and 19 emulator. I have built RecyclerViews with CardViews before and they were white. I don't change the background color anywhere. It appears normal on my API 26 emulator.
This my layout for the cards:
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/text_view_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:text="Name"
android:textColor="#android:color/black"
android:textSize="20sp" />
<ImageView
android:id="#+id/image_view_upload"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_below="#+id/text_view_name" />
</RelativeLayout>
This is my adapter class:
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
private Context mContext;
private List<Upload> mUploads;
public ImageAdapter(Context context, List<Upload> uploads) {
mContext = context;
mUploads = uploads;
}
#Override
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.image_item, parent, false);
return new ImageViewHolder(v);
}
#Override
public void onBindViewHolder(ImageViewHolder holder, int position) {
Upload upload = mUploads.get(position);
holder.textViewName.setText(upload.getName());
Picasso.with(mContext)
.load(upload.getImageUrl())
.fit()
.centerCrop()
.into(holder.imageView);
}
#Override
public int getItemCount() {
return mUploads.size();
}
class ImageViewHolder extends RecyclerView.ViewHolder {
TextView textViewName;
ImageView imageView;
ImageViewHolder(View itemView) {
super(itemView);
textViewName = itemView.findViewById(R.id.text_view_name);
imageView = itemView.findViewById(R.id.image_view_upload);
}
}
}
I load these images from the Firebase storage. As you can see, I didn't change the background color anywhere.
Any idea?
I believe you are passing the wrong context to your adapter to inflate your layout. Try passing activity or fragment context instead of passing applicationConetxt. ApplicationContext does not apply the theme you defined.
OR
if you don't wanna do that. you need to change background color of your carview
like this:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:card="http://schemas.android.com/apk/res-auto"
card:cardBackgroundColor="#color/colorPrimary"
android:layout_margin="8dp">
</android.support.v7.widget.CardView>
I am not sure why it is showing grey on api 21.
But if you want white background then you can set the background color like this.
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="#FFFFFF">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:background="#FFFFFF">
<TextView
android:id="#+id/text_view_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:text="Name"
android:textColor="#android:color/black"
android:textSize="20sp" />
<ImageView
android:id="#+id/image_view_upload"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_below="#+id/text_view_name" />
</RelativeLayout>
Also please note that cardview is supported from api 21 only.
As You can See in This Link
android support(cardView, RecyclerView)library in older versions with target kitkat
Your CardView is Only compatible till API level 26,which is why i asked you to post your Gradle dependencies
You can Try changing the minimum API level and see for any changes
Related
I have an app that displays posts in a Recycler View. The recycler View item has an image, a title and a chip group with hashtags
My problem is that I am getting a weird spacing between the chip group and text when I play the app on my phone or emulator but it looks fine on the preview
What this could possible be?
This is the xml for the recycler View item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:clipToPadding="false"
android:gravity="center_horizontal|top"
android:orientation="vertical"
android:padding="10dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:background="#color/white"
android:clipToPadding="false"
android:elevation="4dp"
android:padding="2dp">
<ImageView
android:id="#+id/imageViewThumbnailRecyclerPost"
android:layout_width="157dp"
android:layout_height="100dp"
android:backgroundTint="#color/dark_gray_eg"
android:foregroundGravity="center"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="#drawable/thumbnail_preview" />
<ImageView
android:id="#+id/imageViewTypeRecyclerPost"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_margin="3dp"
android:layout_marginTop="28dp"
android:layout_marginEnd="4dp"
android:elevation="3dp"
android:foregroundGravity="center"
android:scaleType="centerInside"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/google_slides_icon" />
<ImageView
android:id="#+id/imageViewStatusRecyclerPost"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_margin="3dp"
android:foregroundGravity="center"
android:scaleType="centerInside"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageViewTypeRecyclerPost"
app:srcCompat="#drawable/icon_edited" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="#+id/textViewTitleRecyclerPost"
android:layout_width="157dp"
android:layout_height="wrap_content"
android:layout_marginStart="1dp"
android:layout_marginTop="5dp"
android:inputType="textMultiLine"
android:lines="2"
android:text="A Vinda da fampilia real e a independencia do Brasil"
android:textColor="#color/dark_gray_eg"
android:textSize="13sp"
android:textStyle="bold" />
<com.google.android.material.chip.ChipGroup
android:id="#+id/chipGroupRecyclerPost"
android:layout_width="157dp"
android:layout_height="wrap_content"
android:layout_marginStart="-1dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="-1dp"
app:chipSpacingHorizontal="0dp"
app:chipSpacingVertical="5dp"
app:singleLine="false">
</com.google.android.material.chip.ChipGroup>
</LinearLayout>
This is how it looks like on the preview and should look like on my phone:
This is how it is actually looking like on my phone:
This is how I initialize the recycler:
GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 2);
adapterRecyclerSearch = new AdapterRecyclerSearch(getContext(), postsList);
recyclerViewSearch.setLayoutManager(layoutManager);
recyclerViewSearch.setHasFixedSize(true);
recyclerViewSearch.setAdapter(adapterRecyclerSearch);
This is my adapter:
public class AdapterRecyclerSearch extends RecyclerView.Adapter<AdapterRecyclerSearch.MyViewHolder> {
// list of Posts
public List<DatabasePostHolder> postsList = new ArrayList<>();
public Context context;
public StorageReference storage = FirebaseInstances.getStorageReference();
public StorageReference storageThumbnails = storage.child(Constants.STORAGE_FOLDER_THUMBNAILS);
public AdapterRecyclerSearch(Context context, List<DatabasePostHolder> postsList){
// recieve context for glide and posts list to display
this.context = context;
this.postsList = postsList;
}
public void setPostsList(List<DatabasePostHolder> postsList) {
this.postsList = postsList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View postView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_post_layout, parent, false);
return new MyViewHolder(postView);
}
#SuppressLint("ResourceAsColor")
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
// set hashtag chips
List<String> tagsList = postHolderInPosition.getTags();
holder.chipGroupHashtags.removeAllViews();
for (int i=0; i<tagsList.size(); i++){
Chip chip = (Chip) LayoutInflater.from(context).inflate(R.layout.chip_hashtag_template, holder.chipGroupHashtags, false);
chip.setText("#" + tagsList.get(i));
holder.chipGroupHashtags.addView(chip);
}
}
#Override
public int getItemCount() {
return postsList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
// variables of what will be inside the layout for the adapter
TextView textViewTitle;
ImageView imageThumbnail, imageType, imageStatus;
ChipGroup chipGroupHashtags;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
// define view components from post layouts
textViewTitle = itemView.findViewById(R.id.textViewTitleRecyclerPost);
imageThumbnail = itemView.findViewById(R.id.imageViewThumbnailRecyclerPost);
imageType = itemView.findViewById(R.id.imageViewTypeRecyclerPost);
imageStatus = itemView.findViewById(R.id.imageViewStatusRecyclerPost);
chipGroupHashtags = itemView.findViewById(R.id.chipGroupRecyclerPost);
}
}
}
Adding this to the chip group appearence resource solved it for me
<item name="chipMinTouchTargetSize">0dp</item>
<item name="chipMinHeight">15dp</item>
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>
I have a problem. I got an Stackoverflow Error. I tried reduced the Layout and so on. But nothing worked.
I have a view pager and in the fragments are recyclerviews 4 times. (one in each). The inflater Code
View root = inflater.inflate(R.layout.content_main, container, false);
One Layout in Fragment for example:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
android:id="#+id/list_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_margin="10dp"
android:layout_marginTop="15dp"
android:layout_height="wrap_content" />
And this is the Layout for the ReclerView Item
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android:id="#+id/cv"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_margin="20dp"
android:clickable="true"
android:background="?attr/selectableItemBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center|left"
android:padding="10dp"
android:clickable="true"
android:background="?attr/selectableItemBackground"
>
<ImageView
android:id="#+id/album_cover"
android:layout_width="33dp"
android:layout_height="50dp"
android:layout_marginRight="16dp"
android:src="#drawable/ic_supervisor_account_black_24dp" />
<TextView
android:id="#+id/album_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Artistname"
android:textColor="#000000"
android:textSize="15sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
One Layout has a Relative Layout but it works before I made some changes:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/cv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:background="?attr/selectableItemBackground"
android:layout_margin="10dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:clickable="true"
android:longClickable="true"
android:background="?attr/selectableItemBackground"
>
<ImageView
android:id="#+id/album_cover"
android:layout_width="66dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="16dp"
android:src="#drawable/spring_276014_640" />
<TextView
android:id="#+id/album_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/album_cover"
android:text="Albumtitel"
android:textColor="#000000"
android:textSize="20sp" />
<TextView
android:id="#+id/album_artist"
android:layout_width="wrap_content"
android:layout_marginTop="5dp"
android:layout_height="wrap_content"
android:layout_below="#+id/album_name"
android:layout_toRightOf="#+id/album_cover"
android:text="von Artist xy" />
</RelativeLayout>
</android.support.v7.widget.CardView>
Captureing View Table is not possible because app is going down before it changes the layout.
Bitmaps are scaled.
Here is my Adapter:
public class DefaultAdapter extends RecyclerView.Adapter<DefaultAdapter.SongViewHolder> {
private Context con;
private List<String> names;
boolean useplaylist;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class SongViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView title;
SongViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
title = (TextView)itemView.findViewById(R.id.album_name);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public DefaultAdapter(Context context,List<String> names,boolean playlist) {
con = context;
this.names = names;
useplaylist = playlist;
}
// Create new views (invoked by the layout manager)
#Override
public SongViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.playlist_item, viewGroup, false);
SongViewHolder pvh = new SongViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(SongViewHolder personViewHolder, int i) {
personViewHolder.title.setText(names.get(i));
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return names.size();
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
}
Log:
java.lang.StackOverflowError: stack size 8MB\n
at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6108)
at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6112)
at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6112)
at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6112)
at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6112)
at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6112)
Can somebody help me?
Problem solved.
I don't know where the Error was but maby it was an empty list or the ImageAssets wich I replaced with vector assets and activate the Libary in the Gradle.
For thoos who have the same problem in a viewpage: Deactivate all fragments and enable them single, to test where the error is.
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
I have implemented a layout composed of a CardView inside a CardView using AppCompat Support library for CardView. The first layout is the first layer and the second rests on it. Everything is fine on Lollipop, but as stated by Android dev doc, an extra padding is added in order to create shadows on pre-L versions.
Here is the L version:
and the pre-L version:
I've tried a lot of workarounds from other posts to remove these extra paddings, but nothing worked. I may have missed something but I don't know what.
Here is my layout code (I'm using appcompat-v7 r23):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="80dp"
android:id="#+id/adapter_line_favorites"
android:clickable="false">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
card_view:cardPreventCornerOverlap="false"
card_view:contentPadding="0dp"
card_view:cardCornerRadius="4dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="15dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="false"
android:layout_alignParentRight="false"
android:layout_alignParentEnd="false">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
card_view:cardBackgroundColor="#color/CyanPrimaryDark"
card_view:cardCornerRadius="4dp"
android:id="#+id/line_layout">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_gravity="center_horizontal">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:id="#+id/line_icon"
android:layout_gravity="center"
android:layout_marginTop="15dp" />
</LinearLayout>
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:id="#+id/dropdown"
android:layout_gravity="center_vertical|right"
android:layout_marginRight="20dp"
android:focusableInTouchMode="false"
android:src="#drawable/ic_action_keyboard_arrow_down" />
</FrameLayout>
</android.support.v7.widget.CardView>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/inner_favorite"
android:visibility="gone">
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
If anyone has a good workaround working on L and pre-L versions I'm more than interested!
The problem is that you are using CardView from the support library. This Cardview uses its own padding/shadow mechanism on pre-L (api21.) The only way to fix this is to have your adapter use different card layouts for pre-L devices.
Similar question here.
Here is an example, notice the method "determineLayout()" in createviewholder.
public class adapter_overview extends RecyclerView.Adapter<adapter_overview.AdapterViewHolder>{
public ArrayList<String> vehicleList = new ArrayList<>();
private View itemView;
public adapter_overview(ArrayList<String> vehicleList) {
this.vehicleList.addAll(vehicleList.values());
}
#Override
public int getItemCount() {
return vehicleList.size();
}
#Override
public AdapterViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
itemView = LayoutInflater
.from(viewGroup.getContext())
.inflate(determineLayout(), viewGroup,
return new AdapterViewHolder(itemView);
}
#Override
public void onBindViewHolder(AdapterViewHolder adapterViewHolder, int i) {
//do bind stuff
}
}
public int determineLayout(){
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT ){
return R.layout.card_overview_v19;
}else{
return R.layout.card_overview;
}
}
public static class AdapterViewHolder extends RecyclerView.ViewHolder{
public AdapterViewHolder(View view) {
super(view);
//set up text view/etc
}
}
}