I have an item layout where I display an image, product name, and product image. I must display image in 1:1.5 ration using constraint layout. But when I load a small image, below texts not displaying.
Below is my code of item XML:-
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/coordinatorLayoutCartRoot"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.jackandphantom.circularimageview.RoundedImage
android:id="#+id/imageViewSlider"
android:layout_width="match_parent"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toTopOf="#id/tvTitle"
app:layout_constraintDimensionRatio="WH,1:1.4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:rounded_radius="0"
tools:src="#tools:sample/avatars" />
<TextView
android:id="#+id/tvTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="4dp"
android:text="Fitted crew neck sweater"
android:textColor="#color/colorBlack"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/imageViewSlider" />
<TextView
android:id="#+id/tvPrice"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="4dp"
android:text="$34.00"
android:textColor="#color/colorBlack"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tvTitle" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Output with long image:- https://i.imgur.com/QVnljX6.png
Output with small image:- https://i.imgur.com/0ZwkVwE.png
And if I replace match_parent with wrap_content, app crashes with below error :-
java.lang.IllegalStateException: Pages must fill the whole ViewPager2 (use match_parent)
I have found out that the problem is in inflating view holder.
I had the same issue and solved it changing
ViewBinding.inflate(inflater)
to
ViewBinding.inflate(inflater, parent, false)
While struggling with this problem, I figured it out what's the problem was. My use case was I was using androidx.viewpager2.widget.ViewPager2, and calling normal Views in RecyclerView.
If you notice the error carefully you would see something like this:
java.lang.IllegalStateException: Pages must fill the whole ViewPager2 (use match_parent)
at androidx.viewpager2.widget.ViewPager2$2.onChildViewAttachedToWindow(ViewPager2.java:170)
Second line is the key to main issue. If you open ViewPager2.java you would see
private RecyclerView.OnChildAttachStateChangeListener enforceChildFillListener() {
return new RecyclerView.OnChildAttachStateChangeListener() {
#Override
public void onChildViewAttachedToWindow(#NonNull View view) {
RecyclerView.LayoutParams layoutParams =
(RecyclerView.LayoutParams) view.getLayoutParams();
if (layoutParams.width != LayoutParams.MATCH_PARENT
|| layoutParams.height != LayoutParams.MATCH_PARENT) {
throw new IllegalStateException(
"Pages must fill the whole ViewPager2 (use match_parent)");
}
}
#Override
public void onChildViewDetachedFromWindow(#NonNull View view) {
// nothing
}
};
}
Android is not taking the match_parent assigned in xml to attach views. May be future improvements would be done in next release of ViewPager2.
Anyways, for now to fix it, set layout params as MATCH_PARENT explicity.
view.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
This view is the parent view holding View Pager childs.
In you case it would be androidx.constraintlayout.widget.ConstraintLayout.
view.setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
set width and height in your adapter item of ViewPager2 match_parent
Use match_parent to your viewholder layout of ViewPager2
I have the same error, After sometimes I Found the issue in ViewPager2's adapter item, I changed it from wrap_content to match_parent, and it was Fixed.
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/iv_banner"
android:layout_width="match_parent"
android:layout_height="match_parent"/> <!--Change height here to match_parent-->
You should to write like this:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view: View = inflater.inflate(R.layout.yourlayout, parent, false)
view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
return ViewHolder(view)
}
inner class ViewHolder(itemView: View) :
RecyclerView.ViewHolder(itemView) {
}
For me, the issue was pages (i.e. parent/root layout of the adapter) in ViewPager2 were not match_parent hence the error was
java.lang.IllegalStateException: Pages must fill the whole ViewPager2 (use match_parent)
viewpager2 item should have match_parent width and height. but IF you are using View Binding you should inflate layout such as fragments:
ViewBinding.inflate(inflater, parent, false)
i faced the same problem now , your adapter item width and height has to be match_parent
Possible scenario is also if you dont use parent in inflater.
This crash with exception You have:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OnboardViewHolder {
return OnboardViewHolder(parent.context.inflate(
R.layout.view_onboard_item, null, false
))
}
And this works :
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OnboardViewHolder {
return OnboardViewHolder(parent.context.inflate(
R.layout.view_onboard_item, parent, false
))
}
I had the same problem.
I used ViewPager2 to display the slider. But its XML item was not MATCH_PARENT.
After that change the problem was resolved.
I also faced the same issue, and the solution is to set the height as match_parent of your item view i.e layout used in adapter class must have height as MATCH_PARENT
set android:layout_width & android:layout_height to match_parent of ViewPager2 & adapter layout
If you are using Data binding, try this on the Adapter class
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): BannerViewHolder {
return BannerViewHolder(
HomeShopsBannerCellBinding.inflate(LayoutInflater.from(parent.context),
parent, //add this line
false), //add this line
mListener,
)
}
Also set Match parent for adapter cell layout and viewpager2 layout
I solve this by using wrap_content in parent view of ViewPager2
Example:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".presentation.home.view.BannerFragment">
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/view_pager_banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
So it will take the height of the adapter layout.
I was facing this problem because my viewpager2 was in to a FragmentContainerView with layout_height="wrap_content".
So I changed it to: layout_height="match_parent" and solved the problem :)
If you are using the viewpager2 inside the constraint layout just wrap viewpager2 with a relative layout:
<RelativeLayout
android:id="#+id/sub_service_list_view_cont"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/basket"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view14">
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/sub_service_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
I meet the error as you describe.
First,The problem occured in the recyclerview,so it's no matter with vipager2
Second,What is affected is recycleview's viewholder.
Last,Change the viewholder's width and height,make it is all match parent.
Good luck for you.
I also faced the same issue but when I change the item view height to match parent instead of wrap content it work fine.
for fixed error Pages must fill the whole ViewPager2 (use match_parent) :
Set enough height com.jackandphantom.circularimageview.RoundedImage to match_parent
android:layout_height="match_parent"
Viewpager2 by default forces the pages to be MATCH_PARENT, or an exception will be thrown
A solution for that is to do the following before you do anything to the viewpager. This will prevent the viewpager from throwing an exception when the page size is not MATCH_PARENT. Of course you must make your layout wrap_content in order for this to work.
((RecyclerView) yourViewPager2Object.getChildAt(0)).clearOnChildAttachStateChangeListeners();
Further Explanation.
if you go to the viewpager2 code you will find the following, and what we actually do is disabling this behavior.
/**
* A lot of places in code rely on an assumption that the page fills the whole ViewPager2.
*
* TODO(b/70666617) Allow page width different than width/height 100%/100%
*/
private RecyclerView.OnChildAttachStateChangeListener enforceChildFillListener() {
return new RecyclerView.OnChildAttachStateChangeListener() {
#Override
public void onChildViewAttachedToWindow(#NonNull View view) {
RecyclerView.LayoutParams layoutParams =
(RecyclerView.LayoutParams) view.getLayoutParams();
if (layoutParams.width != LayoutParams.MATCH_PARENT
|| layoutParams.height != LayoutParams.MATCH_PARENT) {
throw new IllegalStateException(
"Pages must fill the whole ViewPager2 (use match_parent)");
}
}
#Override
public void onChildViewDetachedFromWindow(#NonNull View view) {
// nothing
}
};
}
Resources:
https://issuetracker.google.com/issues/70666617
https://gist.github.com/safaorhan/1a541af729c7657426138d18b87d5bd4
I faced this problem and I fixed it just by replacing the
android:layout_height="wrap_content" of item of view pager adapter to
android:layout_height="match_parent"
If you are using RecyclerView as main component and show viewpager2 in this you should use this way;
Main Body;
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="270dp" <!-- Set height to main body on here -->
>
<androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Item Body;
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent" <!-- This one must be match_parent -->
>
<!-- Some components for your item -->
</androidx.constraintlayout.widget.ConstraintLayout>
The layout_width and layout_height of adapter must be match_parent
Related
I need to set the height of the FrameLayout android:id="#+id/heart_strength according to the height of the FrameLayout android:id="#+id/heart_strength_background, whose height is set like this:
<FrameLayout
android:id="#+id/cardiogram_background_light"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="#dimen/default_screen_margin"
android:layout_marginTop="#dimen/chart_widget_margin_top"
android:layout_marginEnd="#dimen/default_screen_margin"
android:background="#drawable/chart_widget_background_light_gray"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.184"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/heart_rate_diagram_background_light" />
<FrameLayout
android:id="#+id/heart_strength_background"
android:layout_width="#dimen/cardiogram_status_bar_width"
android:layout_height="0dp"
android:layout_marginEnd="#dimen/default_screen_margin"
android:background="#drawable/chart_widget_background_dark_gray"
app:layout_constraintBottom_toBottomOf="#+id/cardiogram_background_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#+id/cardiogram_background_light" >
<FrameLayout
android:id="#+id/heart_strength"
android:layout_width="match_parent"
android:layout_height="0dp"
app:heartStrength="#{viewmodel.heartStrengthLiveData}"
android:background="#drawable/chart_widget_background_light_gray"
android:backgroundTint="#color/turquoise"
android:layout_gravity="bottom"/>
</FrameLayout>
When I try to get real height of heart_strength.parent layout with:
#JvmStatic
#BindingAdapter("app:heartStrength")
fun setHeartStrengthViewHeight(bar: FrameLayout, level: Int) {
val barParent = bar.parent as FrameLayout
println("bar parent height: ${barParent.layoutParams.height}")
}
I get 0. How can I know the actual height?
I have a card (cardiogram_background_light). Its height changes dynamically in %. Because of this, the maximum height of the bar located in this card also changes dynamically. Previously, I set its height as maxHeight * Value /100. But now maxHeight dynamically changes on different screen sizes and I want to know its value.
It is because the views are not drawn yet when setHeartStrengthViewHeight is called. To solve this, try the following:
#JvmStatic
#BindingAdapter("app:heartStrength")
fun setHeartStrengthViewHeight(bar: FrameLayout, level: Int) {
val barParent = bar.parent as FrameLayout
val observer : ViewTreeObserver = barParent.viewTreeObserver
observer.addOnGlobalLayoutListener(object: ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
println("bar parent height: ${barParent.height}")
barParent.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})
}
I am creating a simple view where on the top I have some elements and below a recyclerView. When I scroll it down, would like to scroll the whole screen, not the only recycler.
I have achieved it with NestedScrollView, however, now the problem appears. Items in the list will be pretty heavy and in this configuration, all the items are bind at the same time(call of onBindViewHolder).
any ideas how to make them recycle and solve this problem?
Here is my xml file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.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:background="#android:color/darker_gray"
android:orientation="vertical"
tools:context="com.gkuziel.testkotlin.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/ic_available_stores_default" />
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test text" />
<android.support.v7.widget.RecyclerView
android:id="#+id/list_test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:isScrollContainer="false"
android:nestedScrollingEnabled="false">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Update:
The found a sweet solution: you add a complex header as ItemDecoration, its great cause your adapter can stay untouched, you just add sth like this:
recyclerView.addItemDecoration(dividerItemDecoration);
the only drawback of this solution is i couldn't make this header clickable (in my case it contains another recyclerView), however I know some people achieved it as well.
For this moment I decided implement heterogeneous recyclerview, with 1 instance of header type and the rest of simple row types.
What is important, the header type is fully binded once in HeaderViewHolder constructor and onBindViewHolder looks like this:
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is HeaderViewHolder) {
//do nothing
Log.d("ProductAdapter", "Binding: Header")
} else if (holder is ItemViewHolder) {
Log.d("ProductAdapter", "Binding: " + position.toString())
val searchItem = items!![position - 1]
//here the proper binding is going on
}
}
You can try setting the recyclerview layout manager's method canScrollVertical to false and it won't respond to any touch inner scroll events.
override below method and return false.
boolean canScrollVertically()
here it is how to set.
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
// Lookup the recyclerview in activity layout
RecyclerView listTest = (RecyclerView) findViewById(R.id.list_test);
// Attach the adapter to the recyclerview to populate items
listTest.setAdapter(adapter);
// Set layout manager to position the items
listTest.setLayoutManager(new LinearLayoutManager(this){
#Override
public boolean canScrollVertically(){
return false;
}
});
// That's all!
}
I am trying to create this effect
I am using a recycler view but my issue, is that each card is 100% of the width of the screen as apposed to 70%.
Here is the xml code for each item
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rowLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/scale_20dp">
<LinearLayout
android:id="#+id/button_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/currentYear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#drawable/paymentscreengrey"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="35dp"
android:paddingTop="#dimen/scale_50dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/scale_20dp"
android:text="**** **** **** 5432"
android:textColor="#color/white"
android:textSize="#dimen/scale_20dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="2345"
android:textColor="#color/white"
android:textSize="#dimen/scale_16dp" />
If you want the first item to be left-aligned (i.e., reproduce what's in the screenshot), subclass LinearLayoutManager and override the three generate*LayoutParams methods. Here's how I did it: https://gist.github.com/bolot/6f1838d29d5b8a87b5fcadbeb53fb6f0.
class PeekingLinearLayoutManager : LinearLayoutManager {
#JvmOverloads
constructor(context: Context?, #RecyclerView.Orientation orientation: Int = RecyclerView.VERTICAL, reverseLayout: Boolean = false) : super(context, orientation, reverseLayout)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
override fun generateDefaultLayoutParams() =
scaledLayoutParams(super.generateDefaultLayoutParams())
override fun generateLayoutParams(lp: ViewGroup.LayoutParams?) =
scaledLayoutParams(super.generateLayoutParams(lp))
override fun generateLayoutParams(c: Context?, attrs: AttributeSet?) =
scaledLayoutParams(super.generateLayoutParams(c, attrs))
private fun scaledLayoutParams(layoutParams: RecyclerView.LayoutParams) =
layoutParams.apply {
when(orientation) {
HORIZONTAL -> width = (horizontalSpace * ratio).toInt()
VERTICAL -> height = (verticalSpace * ratio).toInt()
}
}
private val horizontalSpace get() = width - paddingStart - paddingEnd
private val verticalSpace get() = height - paddingTop - paddingBottom
private val ratio = 0.9f // change to 0.7f for 70%
}
This solution is based on/inspired by the spanning (i.e., fit all items to screen) linear layout manager https://gist.github.com/heinrichreimer/39f9d2f9023a184d96f8.
Btw, if you just want to show the items to the left and to the right, while the current item is centered, you can add padding to the recycler view and set clipToPadding to false. In this case you don't even need a custom layout manager.
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager">
I needed to have the items in my horizontal RecyclerView to be 70% of the width of the recyclerview. It can be easily done in onCreateViewHolder():
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.row, parent, false);
view.layoutParams = ViewGroup.LayoutParams((parent.width * 0.7).toInt(),ViewGroup.LayoutParams.MATCH_PARENT)
return ViewHolder(view);
}
Two ways of doing this really.
1)Use a custom view for your the recycled view. Override onMeasure to return its width as 70 percent of the screen.
2)In your Recycler View adapter, when you create the view set its width to be 70 percent of the screen's width.
In either case you get the screen size from the Display and just multiply the width by .7. In the first case you set that as the EXACT measured width, in the second you set it in the layout param. The second is probably a bit easier.
I had a similar issue where I had a fragment with a horizontal RecyclerView and wanted each view item's width to be a third of the user's screen. Solved it by adding the following in the constructor of our ViewHolder class (in my case I wanted each view holder to be 1/3 of the screen instead of 70%):
private class OurViewHolder extends RecyclerView.ViewHolder {
...
public OurViewHolder (LayoutInflater inflater, ViewGroup parent) {
super (inflater.inflate (R.layout.list_item_layout, parent, false));
// This code is used to get the screen dimensions of the user's device
DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int width = displayMetrics.widthPixels;
int height = displayMetrics.heightPixels;
// Set the ViewHolder width to be a third of the screen size, and height to wrap content
itemView.setLayoutParams(new RecyclerView.LayoutParams(width/3, RecyclerView.LayoutParams.WRAP_CONTENT));
...
}
...
for your row.xml parent, you must use wrap_content for its width then add this property.
android:paddingLeft="25dp"
You will get same result
Just updated a bit from this answer by adding a margin and getting displayMetrics from the resources to make it clean:
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(product: StyleMaster) = with(itemView) {
val width = context.resources.displayMetrics?.widthPixels
if (width != null) {
val params = RecyclerView.LayoutParams(width / 2, RecyclerView.LayoutParams.WRAP_CONTENT)
params.setMargins(2, 2, 2, 2)
itemView.layoutParams = params
}
// Rest of the code goes here...
Try changing LinearLayout with PercentRelativeLayout to "wrap" the RecyclerView and then set the its width to 70%.
Change this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rv"
/>
</LinearLayout>
With this:
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_widthPercent="70%"
android:id="#+id/rv"
/>
EDIT
Since Percent Support Library comes along with Android Support Library 23 so please make sure that you update Android Support Library in SDK Manager to the latest version already (actually 24). And then add a dependency like below in build.gradle file:
compile 'com.android.support:percent:24.0.0'
I am facing a strange error where recyclerview is showing only a single item. Below is code for my recyclerview adapter :
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<chat> chats;
String username;
final int My=0,Their=1;
public ChatAdapter(List<chat> chats) {
this.chats = chats;
this.username = PushApp.getApp().getSPF().getStringData(Constants.ANAME);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case My:
View v1 = inflater.inflate(R.layout.my_chat_child, parent, false);
viewHolder = new MyChatHolder(v1);
break;
case Their:
View v2 = inflater.inflate(R.layout.their_chat_child, parent, false);
viewHolder = new TheirMessageHolder(v2);
break;
default:
View v = inflater.inflate(R.layout.my_chat_child, parent, false);
viewHolder = new MyChatHolder(v);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case My:
MyChatHolder myChatHolder = (MyChatHolder) holder;
myChatHolder.setMyMessage(chats.get(position).getMessage());
break;
case Their:
TheirMessageHolder theirMessageHolder = (TheirMessageHolder) holder;
theirMessageHolder.setTheirChat(chats.get(position).getFrom(), chats.get(position).getMessage());
break;
}
}
#Override
public int getItemViewType(int position) {
if(username.equalsIgnoreCase(chats.get(position).getFrom()))
return My;
return Their;
}
#Override
public int getItemCount() {
return chats.size();
}}
I have already used this code in other app and its working perfectly. I have checked the chats data which is also perfect.
Here's link to git repo layout files:
layout files
Don't use match_parent for height for your item view. One item fills whole screen vertically so you don't see another.
when you are creating row.xml for recyclerview should follow these things:
Always use "wrap_content" for the height of the row otherwise in "match_parent" it will occupy the whole screen for a single row.
You can also take the height in dp.
My mistake was I accidentally used:
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
instead of:
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
content_main.xml as follows
android:layout_width="match_parent"
android:layout_height="match_parent"
IN row_list.xml file make following changes
android:layout_width="match_parent"
android:layout_height="wrap_content"
I make above changes it runs.
Try changing the layout used in your item view to FrameLayout. Here is an example.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/item"
android:layout_width="match_parent"
android:layout_height="?listPreferredItemHeight"
android:clickable="true"
android:focusable="true"
android:foreground="?selectableItemBackground">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"/>
</FrameLayout>
After checking the log make sure multiple items are added in the list but in UI its showing only 1 item means check this properties.
In item_xml file change property to
Correct Approach
android:layout_width="match_parent"
android:layout_height="wrap_content"
wrong Approach
android:layout_width="match_parent"
android:layout_height="match_parent"
I have this issue today, and after 1001 minutes, I find out this come from this line inside RecyclerView:
android:layout_marginTop="10dp"
My RecyclerView was put inside NestedScrollView, I think that is the indirect cause.
So I put here for anyone else meet the same issue. here the image
1) if your recyclerview is vertical then set height of recyclerview match_parent and row_item.xml height also match_parent
2) if your recyclerview is horizontal then set Width of recyclerview match_parent and row_item.xml Width also match_parent
for ex:-
Horizontal RecyclerView
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="60dp"
android:layout_marginRight="60dp" />
row_item.xml
<TextView
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:background="#drawable/rect"
android:gravity="center"
android:maxLines="2"
android:padding="10dp"
android:textColor="#color/white"
android:textSize="25sp" />
I've got a FrameLayout which I want to grow as time continues.
I've implemented a Runnable-Interface.
public void run() {
time_value++;
FrameLayout fl_dateTime = (FrameLayout)findViewById(R.id.game_DateTime);
LayoutParams lp_fl_dateTime = fl_dateTime.getLayoutParams();
lp_fl_dateTime.width = time_value;
handler.postDelayed(this, 100);
}
Why doesn't this work? O_O
You need to set the layout params back after modifying them.
View#setLayoutParams(ViewGroup.LayoutParams lp)
I was able to do this by setting the initial size of the frame to 0dp and then just setting the minWidth to whatever I wanted.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:background="#android:color/black"
android:id="#id/layout"
android:minHeight="50dp"
android:measureAllChildren="false">
item.setMinimumWidth(10dp);