I am trying to implement scrollable list of buttons.
As shown in screenshot above, there is 3 buttons shown on the screen. I am trying create a list of buttons, that user can scroll them 3 at a time.
I tried 2 ways:
1- View Pager: I created 1 fragment for each 3 buttons.
The scroll works perfectly as I wanted, but when i need to add new button, it is a real overhead work.
2- RecyclerView: Which is works well but doesnt scroll 3 at a time.
So i want to show on screen only 3 items. When user scroll, it will scroll to the next 3 items.
Is it possible to do this with RecyclerView (which is easier to add to it)?
One solution could be using an adapter which shows 3 elements per item, then use the PageSnapHelper to get the paging effect:
The Adapter:
public class ButtonsRecyclerAdapter extends RecyclerView.Adapter<ButtonsRecyclerAdapter.ButtonsViewHolder> {
private List<Button> mButtons = new ArrayList<>();
#Override
public ButtonsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_buttons, null);
return new ButtonsViewHolder(layoutView);
}
#Override
public void onBindViewHolder(ButtonsViewHolder holder, int position) {
int startPosition = getItemCount() * position;
int endPosition = startPosition + 3;
for (int i = startPosition; i < endPosition || i < mButtons.size(); i++) {
Button neededButton = holder.getButton(i - position);
neededButton.setVisibility(View.VISIBLE);
//Do whant you want to do with it
}
}
#Override
public int getItemCount() {
return null != mButtons ? ((int) Math.ceil((double) mButtons.size() / 3)) : 0;
}
public class ButtonsViewHolder extends RecyclerView.ViewHolder {
Button mButtonFirst;
Button mButtonSecond;
Button mButtonThird;
public ButtonsViewHolder(View itemView) {
super(itemView);
mButtonFirst = (Button) itemView.findViewById(R.id.button_first);
mButtonSecond = (Button) itemView.findViewById(R.id.button_second);
mButtonThird = (Button) itemView.findViewById(R.id.button_third);
}
Button getButton(int index) {
switch (index) {
case 0:
return mButtonFirst;
case 1:
return mButtonSecond;
case 2:
return mButtonThird;
}
return null;
}
}
}
The list item layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="#+id/button_first"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"/>
<Button
android:id="#+id/button_second"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"/>
<Button
android:id="#+id/button_third"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"/>
</LinearLayout>
Related
I am using GridLayoutManager for RecyclerView.
There are conditions where i need to draw 1, 2, 3 or 4 items per row. Like following.
I am able to achieve this by doing following.
//RecyclerView
override fun getItemViewType(position: Int): Int {
if(mDataList?.get(position)?.totalColumns == 5){
return COLUMNS_5
}
else if(mDataList?.get(position)?.totalColumns == 4){
return COLUMNS_4
}
}
On Fragment class
mLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
//If there are 6 items in 1 row, then return 1
switch(homeTabLayoutRecyclerAdapter.getItemViewType(position)){
case COLUMNS_5:
return 5;
case COLUMNS_4:
return 4;
The issue is, i am able to get the layout, i shared above, but i need to center all of the items. Like following:
Following is my recyclerview code.
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvItems"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginEnd="24dp"
android:layout_marginStart="24dp"
android:layout_gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/guideline32" />
So this is my code. I am trying to create what looks like a PPT slideshow of images with their title and description in my application.
I have the below code and I am stuck on how to allow the user to:
When he gets into the slideshow he would get the images, with a title and text "description" for each.
when "ENTER" is pressed set the text on that image to invisible.
When the user navigates to the right, the next view(s) would contain a text and Image.
-When the user navigates back left the text view that he set invisible should still be invisible and the has the option to get it to become visible again by just pressing enter.
The last part is what I am stuck on, as I am not able to figure out how each "Linear Layout" inside my viewpager would remember its visibility and act accordingly. (i.e. gets back to visible once it was invisible and vice versa).
I appreciate your input.
Please find the code below:
My ViewPager XML file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/fragment_pager_main_parent"
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"
android:background="#drawable/default_background"
tools:context=".PowerPointActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/fragment_pager_viewPager2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
My views XML file:
<?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:id="#+id/fragment_pager_item_parent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/fragment_pager_item_imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:scaleType="fitXY"/>
<LinearLayout
android:id="#+id/fragment_pager_item_main_child"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="textStart"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="#+id/fragment_pager_item_parent"
app:layout_constraintStart_toStartOf="#+id/fragment_pager_item_parent">
<!-- the linear layout below was not initially here but I was trying to have a layout for each child.-->
<LinearLayout
android:id="#+id/fragment_pager_item_child"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="textStart"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="#+id/fragment_pager_item_parent"
app:layout_constraintStart_toStartOf="#+id/fragment_pager_item_parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/fragment_pager_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:gravity="top"
android:textColor="#FFFFFF"
android:textSize="12dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="#+id/fragment_pager_item_child"
app:layout_constraintTop_toTopOf="#+id/fragment_pager_item_child"
app:layout_constraintVertical_bias="0.0"
tools:text="Topic" />
<TextView
android:id="#+id/fragment_pager_item_about"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="top"
android:layout_marginStart="10dp"
android:elegantTextHeight="true"
android:text="#string/about_topic"
android:textColor="#ffffff"
android:textSize="12sp"
app:layout_constraintHorizontal_bias="10"
app:layout_constraintStart_toStartOf="#+id/fragment_pager_item_title"
app:layout_constraintTop_toBottomOf="#id/fragment_pager_item_title"
app:layout_dodgeInsetEdges="left" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
My Adapter Class:
public class PowerpointAdapter extends RecyclerView.Adapter{
private List<Image> mPowerPointList;
static class PagesViewHolder extends RecyclerView.ViewHolder {
private ImageView mViewImageView;
private TextView mTitleView;
private TextView mDescriptionView;
private LinearLayout mLinearLayout;
public PagesViewHolder(#NonNull View itemView) {
super(itemView);
Timber.i("PagesViewHolder");
mViewImageView = itemView.findViewById(R.id.fragment_pager_item_imageView);
mTitleView = itemView.findViewById((R.id.fragment_pager_item_title));
mDescriptionView = itemView.findViewById(R.id.fragment_pager_item_about);
mLinearLayout = itemView.findViewById(R.id.fragment_pager_item_child);
}
}
public PowerpointAdapter(List<Image> mPowerPointList) { this.mPowerPointList = mPowerPointList;}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Timber.i("onCreateViewHolder");
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_pager_item, parent, false);
return new PagesViewHolder(mView);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
Timber.i("onBindViewHolder");
PagesViewHolder mViewHolder = (PagesViewHolder) holder;
Image powerpoint = mPowerPointList.get(position);
mViewHolder.mViewImageView.setImageResource(powerpoint.getTrialImage());
mViewHolder.mTitleView.setText(powerpoint.getTitle());
mViewHolder.mDescriptionView.setText(powerpoint.getDescription());
mViewHolder.mLinearLayout.setVisibility(View.VISIBLE);
}
#Override
public int getItemCount() {
Timber.i("getItemCount");
return mPowerPointList.size();}
My activity class:
// for a one image display, the image can be treated similarly to a powerpoint.
public class PowerPointActivity extends Activity {
private ViewPager2 viewPager2;
#Override
protected void onCreate(Bundle savedInstanceState) {
Timber.i("onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_pager_main);
ConstraintLayout mLayout = findViewById(R.id.fragment_pager_main_parent);
mLayout.setBackgroundResource(R.color.Transparent_black);
viewPager2 = findViewById(R.id.fragment_pager_viewPager2);
setUpPagerAdapter();
}
/**
* this method will set up the adapter
*/
private void setUpPagerAdapter() {
Timber.i("SetUpPagerAdapter");
PowerpointAdapter pagerAdapter = new PowerpointAdapter(fetchDummyData());
viewPager2.setAdapter(pagerAdapter);
viewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
}
/**
* #return this method will return dummy data in form of list
*/
private List<Image> fetchDummyData() {
Timber.i("fetchDummyData in Power Point Activity");
List<Image> powerpointList = new ArrayList<>();
String[] dummyArrDescriptions = getResources().getStringArray(R.array.array_str_descriptions_for_powerPoints);
String[] dummyArrTitles = getResources().getStringArray(R.array.array_str_titles_for_powerPoints);
for (int index = 0; index < dummyArrTitles.length; ++index) {
Image image = new Image(dummyArrTitles[index], dummyArrDescriptions[index], R.drawable.ppt_image);
powerpointList.add(image);
}
return powerpointList;
}
/**
* this method handles slideshow navigation
*/
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Timber.i("OnKeyDown");
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_LEFT: {
viewPager2.setCurrentItem(viewPager2.getCurrentItem() - 1);
Toast.makeText(PowerPointActivity.this, "Left pressed!", Toast.LENGTH_SHORT).show();
break;
}
case KeyEvent.KEYCODE_DPAD_RIGHT: {
viewPager2.setCurrentItem(viewPager2.getCurrentItem() + 1);
Toast.makeText(PowerPointActivity.this, "Right pressed!", Toast.LENGTH_SHORT).show();
break;
}
case KeyEvent.KEYCODE_BACK: {
Toast.makeText(PowerPointActivity.this, "Back pressed!", Toast.LENGTH_SHORT).show();
super.onBackPressed();
break;
}
// todo: Fix the visibility of each page description
case KeyEvent.KEYCODE_ENTER: {
if (findViewById(R.id.fragment_pager_item_child).isShown()) {
Timber.i("It is shown. Setting it to not shown! "+ viewPager2.getCurrentItem() + " now.");
// here this specific child's text should be set to invisible and remembered. findViewById(R.id.fragment_pager_item_child).setVisibility(View.INVISIBLE);
LinearLayout mLayout = findViewById(R.id.fragment_pager_item_child);
Animation outFade = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fade_out);
mLayout.startAnimation(outFade);
mLayout.startAnimation(outFade);
break;
} else {
Timber.i("It is now not shown. Setting it to shown! " + viewPager2.getCurrentItem() + " now.");
LinearLayout mLayout = findViewById(R.id.fragment_pager_item_child);
Animation aniFade = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fade_in);
mLayout.startAnimation(aniFade);
mLayout.startAnimation(aniFade);
findViewById(R.id.fragment_pager_item_child).setVisibility(View.VISIBLE);
break;
}
}
}
return false;
}
}
Thank you!
From the Android documentation we can find that the Adapter holds the following responsibilities:
Acts as a bridge between an AdapterView and the underlying data for that view.
Provides access to the data items
Responsible for making a View for each item in the data set.
So basically it's not the View's job to remember the child's visibility and act upon it. It's PowerpointAdapter responsibility.
You need a status field in your Image object and change it when the view visibility is changed. Also, don't forget to set the view visibility according to this status variable.
For example:
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
Timber.i("onBindViewHolder");
PagesViewHolder mViewHolder = (PagesViewHolder) holder;
Image powerpoint = mPowerPointList.get(position);
mViewHolder.mViewImageView.setImageResource(powerpoint.getTrialImage());
mViewHolder.mTitleView.setText(powerpoint.getTitle());
mViewHolder.mDescriptionView.setText(powerpoint.getDescription());
if(powerpoint.isLayoutVisibile){
mViewHolder.mLinearLayout.setVisibility(View.VISIBLE);
}else{
mViewHolder.mLinearLayout.setVisibility(View.GONE);
}
}
And Inside your ClickListener you should change this field and notify the PowerpointAdapter of these changes.
I have an Activity that contains a Fragment. Fragment contains a RecyclerView, displaying CardViews.
CardView is very simple, just a TextView and a CustomView. This is the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="100dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="100dp"
android:id="#+id/card_current_heat_cardview"
android:layout_gravity="center_vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:weightSum="4">
<TextView
android:id="#+id/card_current_heat_textview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:textStyle="bold"
android:textColor="#000000"
android:background="#android:color/holo_red_dark"
android:gravity="center_vertical"/>
<com.amige.vm2.CurrentHeatChartView
android:id="#+id/card_current_heat_chart_view"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
TextView should use 1/4 of the width, and the CustomView 3/4.
Im having trouble understanding why weights are ignored the first time the RecyclerView loads
Image of RecyclerView loaded for the first time
But if I scroll up and down, the layout works as expected for some Cards
Image of RecyclerView scrolled up and down
I also have another Activity (no fragment involved here) that has a RecyclerView and IS using this same CardView Layout and it works perfectly!!
I dont know if it has to do with the Fragment...
What am I missing?
Thanks!
EDIT
This the Adapter code
public class MainAdapter extends RecyclerView.Adapter<MyFragment.MainAdapter.ViewHolder>
{
public MainAdapter()
{
}
#Override
public MyFragment.MainAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_current_heat, parent, false);
return new MyFragment.MainAdapter.ViewHolder(v);
}
#Override
public void onBindViewHolder(MyFragment.MainAdapter.ViewHolder holder, int position)
{
if (arrayList.size() == 2)
{
if (position == 0)
{
holder.variableNameTextView.setText(“Var Name”);
holder.currentHeatChartView.reloadChartWithSamples(arrayList.get(0));
}
else
{
if ((position - 1) < arrayList.get(1).size())
{
HashMap variableHashMap = (HashMap) arrayList.get(1).get(position - 1);
holder.variableNameTextView.setText(variableHashMap.get("VarName") != null ? (String)variableHashMap.get("VarName") : "");
holder.currentHeatChartView.reloadChartWithVariableValuesAndColors(variableHashMap, colorGradientsArrayList.get((position - 1) % colorGradientsArrayList.size()));
}
}
}
}
#Override
public int getItemCount()
{
if (arrayList.size() == 2)
{
if (arrayList.get(1).size() > 0)
{
return 1 + arrayList.get(1).size();
}
else
{
return 1;
}
}
return 0;
}
public class ViewHolder extends RecyclerView.ViewHolder
{
TextView variableNameTextView;
CurrentHeatChartView currentHeatChartView;
public ViewHolder(View v)
{
super(v);
this.variableNameTextView = (TextView) v.findViewById(R.id.card_current_heat_textview);
this.currentHeatChartView = (CurrentHeatChartView) v.findViewById(R.id.card_current_heat_chart_view);
}
}
}
I found the culprit.
There was a ConstraintLayout on top of the hierarchy of the Activity containing the Fragment. Since I was working with nested layouts, ConstraintLayout was not the right way to go.
I changed it to RelativeLayout and the cards are now rendered properly.
I think your layout inflation is wrong.
View view = View.inflate(mContext, R.layout.your_layout, null);
If you do like that change your code like this.
View view = LayoutInflater.from(mContext).(R.layout.your_layout, parent, false);
Hope it helps:)
I have used RecyclerView several times before, but it is the first time that it is working too slow.
In this case, the items are represented by a simple LinearLayout with 3 views inside it:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="#+id/linearLayout"
android:orientation="horizontal"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvTicketNumber"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:padding="8dp"/>
<EditText
android:id="#+id/etTotalSold"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:padding="8dp"
android:gravity="center" />
<TextView
android:id="#+id/tvSurplus"
android:layout_width="0dp"
android:layout_weight="1"
android:padding="8dp"
android:layout_height="match_parent"
android:gravity="center"/>
</LinearLayout>
The RecyclerView uses the previous layout in its adapter:
public class TicketAdapter extends RecyclerView.Adapter<TicketAdapter.ViewHolder> {
private ArrayList<Ticket> dataSet;
// Define references to the views for each data item
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvTicketNumber, tvSurplus;
public EditText etQuantity;
public ViewHolder(View v) {
super(v);
tvTicketNumber = (TextView) v.findViewById(R.id.tvTicketNumber);
etQuantity = (EditText) v.findViewById(R.id.etQuantity);
tvSurplus = (TextView) v.findViewById(R.id.tvSurplus);
}
}
public TicketAdapter() {
dataSet = new ArrayList<>();
}
public void setDataSet(ArrayList<Ticket> dataSet) {
this.dataSet = dataSet;
}
private String twoDigits(final int i) {
final String pre = (i<=9 ? "0" : "");
return pre + i;
}
#Override
public TicketAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.table_row, parent, false);
// set the view's size, margins, padding and layout parameters
return new ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// get element from the data set
Ticket ticket = dataSet.get(position);
// replace the contents of the view with that element
holder.tvTicketNumber.setText(twoDigits(position));
holder.tvSurplus.setText("6");
}
#Override
public int getItemCount() {
return dataSet.size();
}
}
Before, I was using TableLayout with TableRows created programmatically, but I have read that layout have to be used for a defined number of rows in XML.
I have to load a list of 100 items in a fragment. But it takes approximately 4 seconds to load. For that reason I wrote some logic to show a progressBar and next hide it and show the scrollView (the recycler is within it).
The fragmentTransaction was still slow, so I moved the code to the onViewCreated method.
The transaction was still slow and I added an AsyncTask. With this last change, the transaction is faster, but the progressBar looks stopped all the time and the buttons can't be used (the onPostExecute is taking 4 seconds to load and show the recyclerView).
I want to show the animation of the progressBar, but the onPostExecute is executed in the UI thread and all the app is stopped for 4 seconds while the RecyclerView is loading.
Please give me some ideas. Before I have used items with images loaded from internet, and the RecyclerView was working faster. It is too strange.
There Fragment. Is it RecyclerView attached below. The bottom line is that by design is the first element should take a little more space than the others. His I increase in ViewHolder of the adapter when rendering as follows:
public class myAdapter extends RecyclerView.Adapter ...
...
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
WeatherForDay weather = mWeathersList.get(position);
holder.mDayTextView.setText(weather.getDay());
//todo update iconManager
//need icon manager, with input -> String, output ->(R.drawable.icon) int
holder.mIconImageView.setImageResource(R.drawable.testicon1);
holder.mTempTextView.setText(weather.getTmp());
if (position == 0) {
if (isFirstBind) {
Log.d(DEBUG_TAG, "is first bind and first position");
holder.setBig();
isFirstBind = false;
}
}
}
...
public void setBig() {
LinearLayout.LayoutParams param = (LinearLayout.LayoutParams) mRoundLayout.getLayoutParams();
int newHeight = (int) (param.height * 1.2f);
int newWidth = (int) (param.height * 1.2f);
param.height = newHeight;
param.width = newWidth;
mRoundLayout.setLayoutParams(param);
mRoundLayout.setBackgroundDrawable(createBigShape(newHeight));
}
private Drawable createBigShape(int newHW) {
GradientDrawable shape = new GradientDrawable();
shape.setShape(GradientDrawable.RECTANGLE);
shape.setCornerRadii(new float[]{newHW, newHW, newHW, newHW, newHW, newHW, newHW, newHW});
shape.setColor(mContext.getResources().getColor(R.color.weryDark));
shape.setStroke(1, mContext.getResources().getColor(R.color.weryDark));
return shape;
}
...
}
How to make elements are aligned along the upper edge and the lower?
P.S. The same problem arises in that the N-element also somehow rendered "large" (on the same device with a large screen N = 13, on the small screen N = 8)
P.S.2 Can eat what is more optimal way to change any element RecyclerView?
item_recycler.xml
<?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="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="#+id/day_text_view_list_item_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/colorWhite"
android:background="#null"/>
<LinearLayout
android:id="#+id/rounded_linear_layout"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="#drawable/round_shape"
android:gravity="center_horizontal"
android:orientation="vertical">
<android.support.v7.widget.AppCompatImageView
android:id="#+id/icon_image_view_list_item_bottom"
android:layout_width="42dp"
android:layout_height="42dp"
android:background="#null"
app:srcCompat="#drawable/testicon1"
tools:ignore="MissingPrefix"/>
<TextView
android:id="#+id/temperature_text_view_list_item_bottom"
android:textColor="#color/colorWhite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"/>
</LinearLayout>
</LinearLayout>
For the gravity issue:
You have to set android:layout_gravity="center_vertical" or android:layout_gravity="center" to your item's root element (LinearLayout).
In addition:
Instead of changing LayoutParams manually, I suggest you to use viewType and create different layouts for position 0 and position > 0. This way, you ensure only position 0 item is bigger and you don't modify it's natural functioning.
You would add this method:
private static final int TYPE_BIG = 0;
private static final int TYPE_STANDARD = 1;
#Override
public int getItemViewType(int position) {
return position == 0 ? TYPE_BIG : TYPE_STANDARD;
}
And modify your onCreateViewHolder:
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layout = viewType == TYPE_BIG
? R.layout.item_recycler_big
: R.layout.item_recycler;
View v = View.inflate(parent.getContext(), layout, parent);
return new ViewHolder(v);
}
And your onBindViewHolder would be as simple as:
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
WeatherForDay weather = mWeathersList.get(position);
holder.mDayTextView.setText(weather.getDay());
holder.mIconImageView.setImageResource(R.drawable.testicon1);
holder.mTempTextView.setText(weather.getTmp());
}
Hope this helps you!
Don't use position that provided from onBindViewHolder(final ViewHolder holder, final int position), it's not permanent (that's why your N-element also "large"). Use holder.getAdapterPosition() instead
Did you try to use some Gravity? For example:
a) Define android:gravity="center_vertical" for RecyclerView item layout
b) Define android:layout_gravity="center_vertical" for mRoundLayout
c) Define android:layout_centerInParent or
android:layout_centerVertical ="true"