I'm trying to create a simple app, where in the main activity there is a ViewPager2 with 3 pages linked to a TabLayout. In each page there is a RecyclerView populated by Cards. Just for testing purposes I tried to populate each page with the same 3 cards, but for some reason in the first page I get the 3 cards but on the next ones I get the 3 cards but there is a lot of blank space between each card so you can only see one card at a time, and I don't understand why that happens. And if I instead of 3 card use 4 or more, in the first page when I scroll down it looks fine but after I scroll back up it has the same problem as the other pages, a lot of blank space. Here is my code:
public class MainActivity extends AppCompatActivity {
String data[] = {"Destaque", "Perto de Si", "Brevemente"};
String evento[] = {"Jola", "Bowling", "Concerto"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager2 viewPager = findViewById(R.id.pager);
viewPager.setAdapter( new SwipeAdapter(this, evento));
TabLayout tabLayout = findViewById(R.id.tabLayout);
new TabLayoutMediator(
tabLayout,
viewPager,
new TabLayoutMediator.TabConfigurationStrategy() {
#Override
public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
tab.setText(data[position]);
}
}
).attach();
}
//
public class SwipeAdapter extends FragmentStateAdapter {
private String evento[];
public SwipeAdapter(MainActivity mainActivity, String evento[]) {
super(mainActivity);
this.evento = evento;
}
#NonNull
#Override
public Fragment createFragment(int position) {
return new RecyclerFragment(evento);
}
#Override
public int getItemCount() {
return 3;
}
}
//
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
String eventos[];
RecyclerAdapter(String eventos[]){
this.eventos = eventos;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View cardView = inflater.inflate(R.layout.card_layout, parent, false);
// Return a new holder instance
return new ViewHolder(cardView);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
String evento = eventos[position];
TextView textView = holder.textView;
ImageView imageView = holder.imageView;
textView.setText(evento);
}
#Override
public int getItemCount() {
return eventos.length;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.card_image);
textView = itemView.findViewById(R.id.card_text);
}
}
}
}
//
public class RecyclerFragment extends Fragment {
String eventos[];
public RecyclerFragment(String eventos[]) {
this.eventos = eventos;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_recycler, container, false);
RecyclerView recyclerView = view.findViewById(R.id.recycler_fragment);
RecyclerAdapter adapter = new RecyclerAdapter(eventos);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
return view;
}
}
XML:
<?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"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tabLayout"
app:layout_constraintVertical_bias="0.0" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="680dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Destaque" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Perto de Si" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Brevemente" />
</com.google.android.material.tabs.TabLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
//
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TestFragment">
<com.google.android.material.card.MaterialCardView
android:id="#+id/card_fragment"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_margin="16dp"
app:cardElevation="5dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/card_image"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:src="#mipmap/beer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/card_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="TextView"
app:layout_constraintStart_toStartOf="#+id/card_image"
app:layout_constraintTop_toBottomOf="#+id/card_image" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</FrameLayout>
//
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".RecyclerFragment">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recycler_fragment"
/>
</FrameLayout>
Change in card_layout.xml
framelayout height android:layout_height="wrap_content"
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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">
<com.google.android.material.card.MaterialCardView
android:id="#+id/card_fragment"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_margin="16dp"
app:cardElevation="5dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/card_image"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:src="#mipmap/ic_launcher"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/card_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="TextView"
app:layout_constraintStart_toStartOf="#+id/card_image"
app:layout_constraintTop_toBottomOf="#+id/card_image" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</FrameLayout>
Related
I've made an adapter with a layout like the one I share below. it went well but, the appearance of each item became untidy.
Here is my code :
public class TableRecyclerAdapter extends RecyclerView.Adapter<TableRecyclerAdapter.ViewHolder> {
private ArrayList<TableModel> data;
private Context context;
private Fragment fragment;
private Dialog dialog;
public TableRecyclerAdapter(Context context, ArrayList<TableModel> data, Fragment fragment, Dialog dialog) {
this.context = context;
this.data = data;
this.fragment = fragment;
this.dialog = dialog;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v = inflater.inflate(R.layout.item_table, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.tvTable.setText(data.get(position).getName());
holder.tvState.setText(data.get(position).getStateString());
holder.bg.setBackgroundColor(Color.parseColor(data.get(position).getWarna()));
holder.tvHtml.setText(Html.fromHtml(data.get(position).getShortInfoHtml()));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
#Override
public int getItemCount() {
return data.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private ImageView paid;
private TextView tvTable, tvHtml, tvState;
private ConstraintLayout bg;
public ViewHolder(View itemView) {
super(itemView);
tvTable = itemView.findViewById(R.id.tvTable);
tvHtml = itemView.findViewById(R.id.tvHtml);
bg = itemView.findViewById(R.id.bg);
tvState = itemView.findViewById(R.id.tvState);
paid = itemView.findViewById(R.id.ivPaid);
}
}
}
This is for layout item
<?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="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
app:cardCornerRadius="10dp"
app:cardElevation="3dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/bg"
android:layout_width="match_parent"
android:background="#drawable/border_button_green"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginStart="12dp"
android:background="#drawable/border_transparent_table"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/tvState"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:text="This text"
android:textColor="#color/color_primary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="#+id/tvTable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="25dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:text="7"
android:textColor="#color/color_primary"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/tvHtml"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:paddingBottom="12dp"
android:text="Example Text"
android:textColor="#color/color_primary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tvTable" />
<ImageView
android:id="#+id/ivPaid"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="4dp"
android:src="#drawable/paid"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
It makes my recyclerview have different heights depending on the text.
I want the items to be the same height per row (maximum height in the row)
Sorry for my english. I hope someone can help me. Thank you
I am trying to implement a nested recycle view i read several post online, but i am still having a difficult time. This is what i did so far, i created a main layout which contains my main Recycle view, i then created the main recycle view row item. And populated it by creating an adapter and implementing it in my main activity. Secondly, i crated a layout with my child recycle view as well as the child recycle view row item. The problem arises when i am trying to access this recycle view, i am unsure as to how to go about doing this? I was able to access my parent recycle and implement the adapter in my main activity, but i am not sure as to how to access my child recycle view. Could someone assist me?
**Parent Recycle View**
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
**Parent Recycle View row**
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view_home"
android:layout_width="130dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:elevation="5dp"
app:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/image_view_movie"
android:layout_width="130dp"
android:layout_height="170dp"
android:scaleType="fitXY"
/>
<LinearLayout
android:id="#+id/layout_mov"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/image_view_movie"
android:layout_margin="1dp"
android:orientation="vertical">
<TextView
android:id="#+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="Mission Impossible"
android:textSize="12sp" />
<TextView
android:id="#+id/tv_genre"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="sans-serif"
android:maxLines="1"
android:text="Action,Comedy..."
android:textSize="12sp" />
</LinearLayout>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
**Child RecycleView**
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tv_movie_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:text="Movie Category"
android:textSize="14sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/home_recycler_view_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/tv_movie_category"
android:layout_marginLeft="10dp"
android:layout_marginBottom="15dp"
android:orientation="horizontal" />
<View
android:id="#+id/activityMainDivider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="#+id/home_recycler_view_horizontal"
android:layout_marginBottom="5dp"
android:background="#31C7C7CC" />
</RelativeLayout>
**Child recycle view row**
<?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/constraintlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15dp">
<androidx.cardview.widget.CardView
android:id="#+id/cardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/newsThumbNail"
android:layout_width="0dp"
android:layout_height="200dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.448"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="#+id/newsTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Dangerous fire is out of control at 24 and park"
android:textSize="17sp"
app:layout_constraintEnd_toEndOf="#+id/newsThumbNail"
app:layout_constraintStart_toStartOf="#+id/newsThumbNail"
app:layout_constraintTop_toBottomOf="#+id/newsThumbNail" />
<TextView
android:id="#+id/newsBody"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="Some text is here"
app:layout_constraintEnd_toEndOf="#+id/newsTitle"
app:layout_constraintStart_toStartOf="#+id/newsTitle"
app:layout_constraintTop_toBottomOf="#+id/newsTitle" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
**Parent Adapter**
public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MessageViewHolder> {
private Context context;
private ArrayList<DataModel> userMessagesList;
public HomeAdapter(Context context, ArrayList<DataModel> userMessageList) {
this.context = context;
this.userMessagesList = userMessageList;
}
#NonNull
#Override
public MessageViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.inner_recycleview_row, viewGroup, false);
return new MessageViewHolder(view);
}
//Loads data into views
#Override
public void onBindViewHolder(#NonNull MessageViewHolder viewHolder, int i) {
// viewHolder.senderTextView.setText(message.getMessage());
viewHolder.senderTextView.setText(userMessagesList.get(i).getName());
viewHolder.receiverTextView.setText(userMessagesList.get(i).getAge());
}
#Override
public int getItemCount() {
return userMessagesList.size();
}
//links up ui elements
static class MessageViewHolder extends RecyclerView.ViewHolder {
private TextView senderTextView, receiverTextView;
public MessageViewHolder(#NonNull View itemView) {
super(itemView);
senderTextView = itemView.findViewById(R.id.tv_genre);
receiverTextView = itemView.findViewById(R.id.tv_title);
}
}
}
**Main Activity**
public class MainActivity extends AppCompatActivity {
private RecyclerView messagesRecycleView;
private ArrayList<DataModel> messageList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
messageList = new ArrayList<>();
initRecycleView();
populateArray();
}
public void populateArray(){
DataModel dataModel1= new DataModel("Bob","18");
messageList.add(dataModel1);
}
//set up RecycleView
public void initRecycleView() {
messagesRecycleView = findViewById(R.id.rv_main);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
//linearLayoutManager.setReverseLayout(true);
messagesRecycleView.setLayoutManager(linearLayoutManager);
HomeAdapter homeAdapter = new HomeAdapter(MainActivity.this, messageList);
messagesRecycleView.setAdapter(homeAdapter);
}
}
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.MessageViewHolder> {
private Context context;
private ArrayList<DataModel> userMessagesList;
public NewsAdapter(Context context, ArrayList<DataModel> userMessageList) {
this.context = context;
this.userMessagesList = userMessageList;
}
#NonNull
#Override
public MessageViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.news_feed_row, viewGroup, false);
return new MessageViewHolder(view);
}
//Loads data into views
#Override
public void onBindViewHolder(#NonNull MessageViewHolder viewHolder, int i) {
// viewHolder.senderTextView.setText(message.getMessage());
viewHolder.senderTextView.setText(userMessagesList.get(i).getName());
viewHolder.receiverTextView.setText(userMessagesList.get(i).getAge());
}
#Override
public int getItemCount() {
return userMessagesList.size();
}
//links up ui elements
static class MessageViewHolder extends RecyclerView.ViewHolder {
private TextView senderTextView, receiverTextView;
public MessageViewHolder(#NonNull View itemView) {
super(itemView);
senderTextView = itemView.findViewById(R.id.newsBody);
receiverTextView = itemView.findViewById(R.id.newsTitle);
}
}
}
I am making an android cv app but I want to implement the UI shown in the screenshot.
screenshot of ui I want
below current UI from real device
current ui
The XML layout where I have implemented my UI, which consists of an ImageView and some TextViews which shows subjects. I have implemented all the tasks but UI is not showing how I want it to show.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:background="#color/colorBlust"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal">
<ImageView
android:id="#+id/educationImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:src="#drawable/education_information"
tools:ignore="ContentDescription" />
<TextView
android:id="#+id/education_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:text="#string/education_information"
android:textColor="#color/colorWhite"
android:textSize="20sp" />
</LinearLayout>
<TextView
android:id="#+id/duration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:text="#string/text_duration"
android:textColor="#color/colorWhite"
android:textSize="16sp" />
<TextView
android:id="#+id/institution"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:text="#string/text_institution"
android:textColor="#color/colorWhite"
android:textSize="16sp" />
<TextView
android:id="#+id/degree"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:text="#string/text_degree"
android:textColor="#color/colorWhite"
android:textSize="16sp" />
<Space
android:layout_width="50dp"
android:layout_height="50dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="#+id/subjectImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:src="#drawable/university_subjects"
tools:ignore="ContentDescription" />
<TextView
android:id="#+id/subjects"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="100dp"
android:layout_marginLeft="100dp"
android:text="#string/university_subjects"
android:textColor="#color/colorWhite"
android:textSize="20sp" />
<include
layout="#layout/subject_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/subjects"
android:layout_marginTop="60dp" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
I have created another adapter and created dummy data in subjectivity
below adapter class
public class SubjectAdapter extends RecyclerView.Adapter<SubjectAdapter.ViewHolder> {
private SubjectActivity subjectActivity;
private int [] subjectImage;
String[] subjectText;
List<FakeData> fakeData;
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView subjects;
public ImageView subjectImage;
public ViewHolder(View view) {
super(view);
subjectImage = (ImageView) view.findViewById(R.id.subjectImage);
subjects = (TextView) view.findViewById(R.id.subjects);
}
}
public SubjectAdapter(SubjectActivity subjectActivity, int []subjectImage, String [] subjectText, List<FakeData> fakeData){
this.subjectActivity = subjectActivity;
this.subjectImage = subjectImage;
this.subjectText = subjectText;
this.fakeData = fakeData;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.subject_list, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
FakeData fake = fakeData.get(position);
Picasso.get().load(fake.getImage()).
into(holder.subjectImage);
holder.subjects.setText(fake.getSubjects());
}
// TODO Auto-generated constructor stub
#Override
public int getItemCount() {
return fakeData.size() ;
}
}
below subject XML where I have hosted RecyclerView
<RelativeLayout 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.support.v7.widget.RecyclerView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true">
</android.support.v7.widget.RecyclerView>
below subject_list.xml where I have host items
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorBlust"
android:orientation="horizontal" >
<ImageView
android:id="#+id/icon"
android:layout_width="60dp"
android:layout_marginLeft="10dp"
android:layout_height="60dp"
android:padding="5dp"
android:src="#drawable/computer_science"
android:layout_marginStart="10dp" />
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/computers_science"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:padding="2dp"
android:textColor="#color/colorWhite" />
</LinearLayout>
I have created fake data in order to host other images and texts
below fakeModel class
public class FakeData {
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getSubjects() {
return subjects;
}
public void setSubjects(String subjects) {
this.subjects = subjects;
}
String image;
String subjects;
}
below adapter class where I have extended with RecyclerView
public class SubjectAdapter extends RecyclerView.Adapter {
private SubjectActivity subjectActivity;
private int [] subjectImage;
String[] subjectText;
List<FakeData> fakeData;
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView subjects;
public ImageView subjectImage;
public ViewHolder(View view) {
super(view);
subjectImage = (ImageView) view.findViewById(R.id.subjectImage);
subjects = (TextView) view.findViewById(R.id.subjects);
}
}
public SubjectAdapter(SubjectActivity subjectActivity, int []subjectImage, String [] subjectText, List<FakeData> fakeData){
this.subjectActivity = subjectActivity;
this.subjectImage = subjectImage;
this.subjectText = subjectText;
this.fakeData = fakeData;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.subject_list, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
FakeData fake = fakeData.get(position);
Picasso.get().load(fake.getImage()).
into(holder.subjectImage);
holder.subjects.setText(fake.getSubjects());
}
// TODO Auto-generated constructor stub
#Override
public int getItemCount() {
return fakeData.size() ;
}
}
below My Subject class where I have implemented fake images and data
public class SubjectActivity extends Activity {
List<FakeData> fakeData;
int [] subjectImage = {R.drawable.computer_science,
R.drawable.data_structure,
};
ListView list;
String[] subjectText = {
"Computer Science",
"Data Structure",
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.subject);
RecyclerView recyclerView= (RecyclerView) findViewById(R.id.list);
SubjectAdapter adapter = new SubjectAdapter(SubjectActivity.this, subjectImage,
subjectText, fakeData);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(adapter);
}
}
This looks like you only have used Android Studio's drag and drop feature to position the UI elements. The problem is, Android Studio shows those UI elements in a generic device, which wont match all devices. When I was starting off with Android, this document helped me a lot to understand how elements in the UI must be placed.
https://developer.android.com/studio/write/layout-editor
You XML is malformed. Your LinearLayout orientation is wrong:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
It should be vertical.
Then validate its content. You have multiple RelativeLayout with orientation attribute.
It should be LinearLayout instead. RelativeLayouts don’t have orientation.
Besides those errors, your layout is very complex and have a deep hierarchy. This will lead to performance issues. My suggestion to you is to learn how to use ConstraintLayout.
The learning curve is a bit high, but it will be worth it!
I am creating a Fragment that has 5 horizontal recycler views under a vertical Scroll View but each time this fragment needs to be loaded, the UI freezes for about a second.
I have created an Adapter that sets the Data from 2 different POJOs into the different Recycler Views. I have found out that the line from my code which seems to be causing the issue is the setLayoutManager() because once commented, the fragment loading does not freeze the UI. Apart from that I haven't been able to find out why is that happening when assigning the LayoutManger to the recycler view and what could I do to improve the fragment's performance.
Here is the fragment_home.xml
<FrameLayout 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"
tools:context="com.entertainment.logicaldays.planetmovie.views.fragments.HomeFragment"
android:id="#+id/layout"
android:background="#color/colorPrimary">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scroll_view">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="#+id/view_pager"
android:layout_marginBottom="5dp">
</android.support.v4.view.ViewPager>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_popular_movies"
android:orientation="horizontal">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_upcoming_movies"
android:orientation="horizontal">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_top_rated_movies"
android:orientation="horizontal">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_popular_tv_shows"
android:orientation="horizontal">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_top_rated_tv_shows"
android:orientation="horizontal">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</ScrollView>
</FrameLayout>
Then I have the recycler_item.xml to bind to the Recycler Views:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/hover_values">
<ImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:src="#drawable/ic_launcher_background"
android:layout_gravity="center|top"
android:id="#+id/recycler_image" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentTop="true"
android:layout_marginTop="20dp"
android:alpha="0"
android:id="#+id/poster_hover_image"
android:layout_centerHorizontal="true"
android:src="#drawable/star"/>
<TextView
android:layout_marginTop="5dp"
android:alpha="0"
android:id="#+id/poster_hover_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/poster_hover_image"
android:fontFamily="#font/theboldfont"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:scrollHorizontally="true"
android:minLines="2"
android:maxLines="2"
android:ellipsize="end"
android:id="#+id/recycler_title"/>
</LinearLayout>
</LinearLayout>
The Adapter which can bind 2 different POJOs into the Recycler Views:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{
public Object pojo;
public Context context;
public RecyclerViewAdapter(Context ctx, Object movies) {
this.pojo = movies;
this.context = ctx;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
final ValueAnimator animatorPosterTint = ValueAnimator.ofInt(0, 180);
final ValueAnimator animatorHoverOpacity = ValueAnimator.ofFloat(0, 1);
//When long-pressing the Movie
view.setOnLongClickListener(new LongClickOnPosterItemListerner(view, animatorPosterTint, animatorHoverOpacity));
//When releasing the touch on the movie
view.setOnTouchListener(new ReleasePosterItemListener(view, animatorPosterTint, animatorHoverOpacity));
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
if(pojo instanceof MovieList) {
holder.title.setText(((MovieList)pojo).results.get(position).title);
Glide.with(context)
.asBitmap()
.load(Utils.BASE_TMDB_POSTER_URL + ((MovieList)pojo).results.get(position).posterPath)
.into(holder.image);
holder.rating.setText(Float.toString(((MovieList)pojo).results.get(position).voteAverage));
}
else{
holder.title.setText(((TVList)pojo).results.get(position).name);
Glide.with(context)
.asBitmap()
.load(Utils.BASE_TMDB_POSTER_URL + ((TVList)pojo).results.get(position).posterPath)
.into(holder.image);
holder.rating.setText(Float.toString(((TVList)pojo).results.get(position).voteAverage));
}
}
#Override
public int getItemCount() {
int count = 0;
if(pojo instanceof MovieList && ((MovieList)pojo).results != null) {
if (((MovieList)pojo).results != null) {
count = ((MovieList)pojo).results.size();
}
}
else{
if (((TVList)pojo).results != null) {
count = ((TVList)pojo).results.size();
}
}
return count;
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView image;
TextView title;
TextView rating;
public ViewHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.recycler_image);
title = itemView.findViewById(R.id.recycler_title);
rating = itemView.findViewById(R.id.poster_hover_text);
}
}
}
And finally we have the HomeFragment.java
public class HomeFragment extends Fragment {
public MainActivity mainActivity;
#BindView(R.id.recycler_popular_movies)
RecyclerView recyclerPopularMovies;
#BindView(R.id.recycler_upcoming_movies)
RecyclerView recyclerUpcomingMovies;
#BindView(R.id.recycler_top_rated_movies)
RecyclerView recyclerTopRatedMovies;
#BindView(R.id.recycler_popular_tv_shows)
RecyclerView recyclerPopularTVShows;
#BindView(R.id.recycler_top_rated_tv_shows)
RecyclerView recyclerTopRatedTVShows;
#BindView(R.id.view_pager)
ViewPager viewPager;
LinkedHashMap<Utils.RequestsToLoad, Boolean> requestsToLoad;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mainActivity = (MainActivity) getActivity();
// Inflate the layout into the Fragment
View v = inflater.inflate(R.layout.fragment_home, container, false);
ButterKnife.bind(this, v);
startViewPager();
startRecyclerViews();
return v;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void startRecyclerViews(){
displayRecyclerView(recyclerPopularMovies, mainActivity.popularMovies);
displayRecyclerView(recyclerTopRatedMovies, mainActivity.upcomingMovies);
displayRecyclerView(recyclerUpcomingMovies, mainActivity.topRatedMovies);
displayRecyclerView(recyclerPopularTVShows, mainActivity.popularTVShow);
displayRecyclerView(recyclerTopRatedTVShows, mainActivity.topRatedTVShow);
}
private void displayRecyclerView(RecyclerView recyclerView, Object object){
LinearLayoutManager layoutManager = new LinearLayoutManager(mainActivity, LinearLayoutManager.HORIZONTAL, false);
final RecyclerViewAdapter adapter = new RecyclerViewAdapter(getActivity(), object);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(layoutManager);
}
private void startViewPager(){
SwipeAdapter swipeAdapter = new SwipeAdapter(getActivity(), mainActivity.upcomingMovies);
viewPager.setAdapter(swipeAdapter);
}
}
As said before, is there anything that could be causing that delay to load the fragment so that I can improve it?
Thanks in advance
I am searching for a long time on net. But no use. Please help or try to give some ideas how to solve this problem.
1. Bug Description
image link:https://i.stack.imgur.com/ixvdB.jpg
"left":Run the apk
"Right":When I swipe down, the size of the items is changing.
2. Code
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
List<Member> memberList = new ArrayList<>();
memberList.add(new Member(1, R.drawable.baishatunbeach1, "白沙屯海灘1"));
//add Members
recyclerView.setAdapter(new MemberAdapter(this, memberList));
}
private class MemberAdapter extends RecyclerView.Adapter<MemberAdapter.ViewHolder> {
private Context context;
private List<Member> memberList;
MemberAdapter(Context context, List<Member> memberList) {
this.context = context;
this.memberList = memberList;
}
#Override
public MemberAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recyclerview_cardview_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(MemberAdapter.ViewHolder holder, int position) {
final Member member = memberList.get(position);
holder.imageId.setImageResource(member.getImage());
holder.textId.setText(String.valueOf(member.getId()));
holder.textName.setText(member.getName());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ImageView imageView = new ImageView(context);
imageView.setImageResource(member.getImage());
Toast toast = new Toast(context);
toast.setView(imageView);
toast.setDuration(Toast.LENGTH_SHORT);
toast.show();
}
});
}
#Override
public int getItemCount() {
return memberList.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
ImageView imageId;
TextView textId, textName;
ViewHolder(View itemView) {
super(itemView);
imageId = (ImageView) itemView.findViewById(R.id.imageId);
textId = (TextView) itemView.findViewById(R.id.textId);
textName = (TextView) itemView.findViewById(R.id.textName);
}
}
}
}
activity_main.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
recyclerview_cardview_item.xml
<android.support.v7.widget.CardView
android:id="#+id/cardview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="6dp"
android:padding="6dp"
app:cardBackgroundColor="#ffdddddd"
app:cardCornerRadius="28dp"
app:cardElevation="6dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/imageId"
android:layout_width="120dp"
android:layout_height="160dp"
android:layout_marginStart="16dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/textId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:layout_marginStart="20dp" />
<TextView
android:id="#+id/textName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:layout_marginStart="24dp" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
You need to change the height of cardview and linearlayout to wrap_content
<android.support.v7.widget.CardView
android:id="#+id/cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="6dp"
android:padding="6dp"
app:cardBackgroundColor="#ffdddddd"
app:cardCornerRadius="28dp"
app:cardElevation="6dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">