I have the following recycler view inside a Constraint Layout (very simple)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".activities.PokemonFavoritesActivity"
tools:showIn="#layout/activity_pokemon_favorites">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_pokemon_favorites"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
And here is the method where I initialize the Recycler View:
private void initializeRecyclerViewComponents() {
favoritesRecyclerView = findViewById(R.id.rv_pokemon_favorites);
layoutManager = new GridLayoutManager(this, 4);
favoritesRecyclerView.setLayoutManager(layoutManager);
pokemonFavoritesAdapter = new PokemonFavoritesAdapter(this, favoritePokemon);
pokemonFavoritesAdapter.setClickListener(this);
favoritesRecyclerView.setAdapter(pokemonFavoritesAdapter);
}
And here is the item_layout:
<?xml version="1.0" encoding="utf-8"?>
<com.mikhaellopez.circularimageview.CircularImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/civ_pokemon_favorite"
android:layout_width="100dp"
android:layout_height="100dp" />
However , as you can see in the image , the view is not "centered" (there is a lot of extra margin at the end of each row in comparison to the start)
How can I do to center the 4 columns in order to have the same start and end spacing ?
Try wrapping your item view in a linearlayout and center the image in this. That should fix it.
My RecyclerView and item has match_parent width but the result is :
<view
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
and items:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:fab="http://schemas.android.com/apk/res-auto"
android:id="#+id/ll_itm"
android:orientation="horizontal"
android:layout_width="match_parent"
full:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:fab="http://schemas.android.com/apk/res-auto"
android:id="#+id/ll_itm"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="100"
android:gravity="right"
>
<Button
android:layout_width="0dp"
android:layout_weight="15"
android:layout_height="fill_parent"
android:text="ملاحظات"
android:id="#+id/button" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="20"
android:gravity="center"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<com.getbase.floatingactionbutton.FloatingActionButton
android:layout_width="fill_parent"
android:layout_height="fill_parent"
fab:fab_plusIconColor="#ff56ff83"
fab:fab_colorNormal="#color/d_red"
fab:fab_colorPressed="#ff5c86ff"
fab:fab_size="mini"
fab:fab_icon="#drawable/ic_remove_white"
android:id="#+id/fab_rmv" />
<esfandune.ir.elmikarbordiardakan.other.CustomTxtView
android:layout_weight="25"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="0"
android:gravity="right|center_vertical"
android:id="#+id/txt_takhir_itm" />
<com.getbase.floatingactionbutton.FloatingActionButton
android:layout_width="fill_parent"
android:layout_height="fill_parent"
fab:fab_plusIconColor="#color/colorprimarylight"
fab:fab_colorNormal="#color/colorprimarydark"
fab:fab_colorPressed="#color/colorprimary"
fab:fab_size="mini"
fab:fab_icon="#drawable/ic_add_white"
android:id="#+id/fab_add" />
</LinearLayout>
</LinearLayout>
<Spinner
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="10"
android:id="#+id/sp_nomre_itm"
android:entries="#array/degrees"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="10"
android:gravity="center"
>
<!--LinearLayout baraye ine ke nameshod fab ro weight behosh dad-->
<com.getbase.floatingactionbutton.FloatingActionButton
android:layout_width="fill_parent"
android:layout_height="fill_parent"
fab:fab_plusIconColor="#ff56ff83"
fab:fab_colorNormal="#color/d_green"
fab:fab_colorPressed="#color/d_orange"
fab:fab_size="normal"
fab:fab_icon="#drawable/ic_done_white"
android:id="#+id/fab_hazr" />
</LinearLayout>
<esfandune.ir.elmikarbordiardakan.other.CustomTxtView
android:layout_weight="5"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="100"
android:gravity="right|center_vertical"
android:id="#+id/txt_ghybtNumber_itm" />
<esfandune.ir.elmikarbordiardakan.other.CustomTxtView
android:layout_weight="30"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="عباسعلی ملاحسینی اردکانی"
android:gravity="right|center_vertical"
android:id="#+id/txt_title_itm"
android:layout_marginRight="10dp"
/>
<view
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="10"
class="de.hdodenhof.circleimageview.CircleImageView"
android:id="#+id/view"
android:src="#drawable/mmrdf"
/>
</LinearLayout>
In your adapter where you are inflating the item in onCreateViewHolder, is the second parameter of the inflate call null?.
If so change it to parent which is the first parameter in the onCreateViewHolder function signature.
View rootView = LayoutInflater.from(context).inflate(R.layout.itemLayout, parent, false);
If you need the second parameter to be null then when you get the view reference on inflating, do the following
View rootView = LayoutInflater.from(context).inflate(R.layout.itemLayout, null, false);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
rootView.setLayoutParams(lp);
return new RecyclerViewHolder(rootView);
Inside onCreateViewHolder(...) method of adapter where you are inflating the view.. you have to define the ViewGroup as the parent.This you will get from the 1st parameter of onCreateViewHolder(...) method.
see the below line in the second parameter i'm passing the ViewGroup. This will automatically match the view to its parent:
rowView=inflater.inflate(R.layout.home_custom_list, parent,false);
///the complete code is below
public View onCreateViewHolder(ViewGroup parent, int position) {
// TODO Auto-generated method stub
View rowView;
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView=inflater.inflate(R.layout.home_custom_list, parent,false);
I was using a FrameLayout with MATCH_PARENT for width and was seeing the same behavior with a RecyclerView + LinearLayoutManager. None of the above changes worked for me until I did the following in the onCreateViewHolder callback:
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.note_layout, parent, false);
v.setLayoutParams(new RecyclerView.LayoutParams(
((RecyclerView) parent).getLayoutManager().getWidth(),
context.getResources()
.getDimensionPixelSize(R.dimen.note_item_height)));
return new ViewHolder(v);
}
Clearly looks like a bug in (I'm guessing) the RecyclerView implementation.
try this when you set layout params for your item in adapter.
View viewHolder= LayoutInflater.from(parent.getContext())
.inflate(R.layout.item, parent, false);
viewHolder.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));
ViewOffersHolder viewOffersHolder = new ViewOffersHolder(viewHolder);
return viewOffersHolder;
I had done fix like this. In my case problem with activity layout file because i am using ConstraintLayout as root activity layout.Might be case for you too.
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/toolBar"
layout="#layout/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/accent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/toolBar" />
</android.support.constraint.ConstraintLayout>
This worked for me.
replace this
View view = View.inflate(parent.getContext(), R.layout.row_timeline, null);
return new TimeLineViewHolder(view, viewType);
by this
View rootView = LayoutInflater.from(context).inflate(R.layout.row_timeline, null, false);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
rootView.setLayoutParams(lp);
return new TimeLineViewHolder(rootView, viewType);
In my case, the problem was in RecyclerView XML declaration, the layout_width was 0dp which means match_constraints, when I changed it to match_parent, items started to fill all RecyclerView width:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp" <-- changed this to "match_parent"
android:layout_height="0dp"
android:layout_marginBottom="45dp"
android:background="#android:color/transparent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_default="wrap"
app:layout_constraintHeight_max="360dp"
app:layout_constraintHeight_min="60dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/header"/>
Simply adding a dummy View with 0 height and full width in root worked for me.
<androidx.core.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="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".screen.gallery.GalleryFragment">
<!----DUMMY VIEW----->
<View
android:layout_width="match_parent"
android:layout_height="0dp"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/navigationList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
/>
I solved this with:
myInflatedRowLayout.getLayoutParams().width = vg.getWidth();
It is replacing the MATCH_PARENT with the actual width of the RecyclerView.
I was facing the same problem when using Linear layout and constraint layout for my compound view used in recycler view, but it worked when I change to relative layout for those compound views.
I've been stuck with this problem for a while, and the solution that worked for me was placing 2 views with match_parent, one inside the other.
If I did this on my list item's layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#F00"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent">
</RelativeLayout>
although it is a relative layout as others have mentioned, and I am passing the parent view but false in the inflater, it would simply not show up at all (red background to check).
But, when I did this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:background="#0F0"
android:layout_height="match_parent"/>
</RelativeLayout>
The green layout showed up and took up the whole space.
So just having a child view inside the main one with match_parent solves the problem, no idea why.
Can't see your full code, but can guess, that some of the views inside your LinearLayout are 'wrap_content'. You need to make one or some of them expand to the full width by using 'android:layout_weight="1"'
update:
you have a lot of redundant layout_weight's. Make them all 'wrap_content' and for only one of them add layout_weight=1 - for the last CustomTextView. This way, it will occupy all the blank space.
I need to hide the visibility of my layout but because it's an included layout with the merge tag I'm not being able to do it. I'm using kotlin and keep getting a null pointer exception when trying to hide the view by using
layout_bookings_past.visibility = View.GONE
with this import
import kotlinx.android.synthetic.main.layout_bookings_past.*
but tried also with
import kotlinx.android.synthetic.main.fragment_bookings.*
That's my code:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/layout_bookings_past"
layout="#layout/layout_bookings_past" />
</android.support.constraint.ConstraintLayout>
And for the merge layout I have something like:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
Thanks very much.
Ps: I've a sample app that simulates the structure of my project here
When you use <merge> tag, merged views are actually merged right into parent ConstraintLayout, so ViewGroup with id layout_bookings_past doesn't exist.
To make sure you can check your layout in Layout Inspector:
You can notice, that tv_past and rv_past are childs of ConstraintLayout that is root layout of FragmentBookings.
The solution would be to add actual ViewGroup instead of <merge> like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
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">
<TextView
android:id="#+id/tv_past"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Past bookings"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/ll_buttons" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_past"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tv_past"
tools:itemCount="2"/>
</android.support.constraint.ConstraintLayout>
There's another option, if we assume, that we always include this layout to ConstraintLayout. You can add android.support.constraint.Group (more info) as a child of <merge> and reference it in your code. Like this:
<android.support.constraint.Group
android:id="#+id/merged_layout"
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="tv_past,rv_past"/>
And just reference it as usually:
merged_layout.visibility = View.GONE
But I guess it is just easier to add ConstraintLayout as parent of the layout. Getting rid of redundant layouts is good, but not worth it in that case.
I guess it's ok to set background color in some average fragment with average layout, but here I've got PreferenceFragment, which layout (PreferenceScreen) doesn't support android:background field. What's a neat way to handle it?
Add following to PreferenceFragment class declaration
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
if (view != null) {
view.setBackgroundColor(getResources().getColor(android.R.color.background_dark));
}
return view;
}
Adding my answer since I had a similar issue with PreferenceFragmentCompat that wasn't quite resolved by just adding a color to the background, and this was a top result while googling the problem.
I had the same issue where using PreferenceFragmentCompat would work, but the settings background was transparent and you could still see views in the underlying activty - changing .add() to .replace() in the getSupportFragmentManger yielded the same overlay.
The solution of changing the background color worked. However, for my build the getColor() method was deprecated. I instead use the following code.
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getListView().setBackgroundColor(Color.WHITE);
}
This solved the transparency issue except for one button, which was still clickable. For the sake of brevity, the issue was I was trying to replace the layout that contained the activity views.
What ended up working was creating an empty layout at the highest order and using .replace() on that layout. The buttons are now covered and no longer clickable.
XML where button was still visible above preferences fragment.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context=".MainActivity">
<!--I was replacing this layout that had all the activity views-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="parent">
<TextView
android:text="Z"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/earth_acc_z"
app:layout_constraintTop_toBottomOf="#+id/earth_acc_y"
app:layout_constraintStart_toStartOf="#+id/earth_acc_y"
app:layout_constraintEnd_toEndOf="#+id/earth_acc_y"
app:layout_constraintHorizontal_bias="1.0"/>
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button" android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/toggleRecording"
app:layout_constraintStart_toStartOf="#+id/toggleRecording"
android:layout_marginStart="8dp"/>
</FrameLayout>
</android.support.constraint.ConstraintLayout>
XML of working example with new empty constraint.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context=".MainActivity">
<!--FrameLayout with two nested ConstraintLayouts-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="parent">
<!--ConstraintLayout with acitivty views-->
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent" android:id="#+id/frameLayout">
<TextView
android:text="Z"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/earth_acc_z"
app:layout_constraintTop_toBottomOf="#+id/earth_acc_y"
app:layout_constraintStart_toStartOf="#+id/earth_acc_y"
app:layout_constraintEnd_toEndOf="#+id/earth_acc_y"
app:layout_constraintHorizontal_bias="1.0"/>
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button" android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/toggleRecording"
app:layout_constraintStart_toStartOf="#+id/toggleRecording"
android:layout_marginStart="8dp"/>
</android.support.constraint.ConstraintLayout>
<!--Preference fragment should replace this empty layout-->
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/preferenceFragment"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
</android.support.constraint.ConstraintLayout>
</FrameLayout>
</android.support.constraint.ConstraintLayout>
I have a common layout (common.xml) which I want to include many times in another layout (layout_a.xml). But it only shows me just one time. Why?
common.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#android:drawable/alert_light_frame">
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:id="#+id/imageView"
android:src="#drawable/test"
android:scaleType="centerCrop" />
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_below="#+id/imageView"
android:id="#+id/textView"
android:text="test"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp" />
</RelativeLayout>
</merge>
layout_a.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/common" />
<include layout="#layout/common" />
</LinearLayout>
The ids when defined in XML must be unique. You are including two layouts that have views that contain the same id.
Here is how you would go about fixing it.
p.s. Unless there is more code that you are not including in your first layout file, that merge tag is useless.
As btse said, the ids in the XML must be unique.
It can be achieved in this way:
<include android:id="#+id/common1"
layout="#layout/common" />
<include android:id="#+id/common2"
layout="#layout/common" />
For information about how to access the elements inside those two included views, you can check out this blog post.
That's what I had done in my Project with Inflater.
test1is just a Layout made with a LinearLayout(Vertical) with text and a button and mainofferslayout in that case, the main layout with an image.
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_offers_display, container, false);
View inflatedLayout = inflater.inflate(R.layout.test1, (ViewGroup) view, false);
LinearLayout ll = (LinearLayout) view.findViewById(R.id.mainofferslayout);
ll.addView(inflater.inflate(R.layout.test1, (ViewGroup) view, false));
ll.addView(inflater.inflate(R.layout.test1, (ViewGroup) view, false));
ll.addView(inflater.inflate(R.layout.test1, (ViewGroup) view, false));
I fixed by setting the layout_height of the RelativeLayout to 250dp since they are overlapped.