Why are ViewPager and GridLayout with 30 elements so slow?

I have a ViewPager and a GridView to display a monthly calendar. GridView has about 30 elements and swipe left and right very slowly. I made a sample project for testing without access to the database, and it is also slow. Maybe someone sees the problem or do I need to do asynchronous page loading?

This is the layout for a single item in a GridView . I want to show 9 small 5x5 pixels icons in any element, but without them it is also slow.

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/Layout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:padding="1dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/date" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="5dp" android:gravity="center_vertical" android:textSize="14sp" android:textStyle="bold"/> </LinearLayout> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <ImageView android:id="@+id/dot1" android:layout_width="wrap_content" android:drawingCacheQuality="auto" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:background="#ffffff" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:paddingBottom="1dp" android:paddingLeft="1dp" android:paddingTop="5dp"/> </RelativeLayout> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <ImageView android:id="@+id/dot2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> </RelativeLayout> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <ImageView android:id="@+id/dot3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="right" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> </RelativeLayout> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <ImageView android:id="@+id/dot4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_gravity="center_horizontal" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> </RelativeLayout> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <ImageView android:id="@+id/dot5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_gravity="left" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> </RelativeLayout> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <ImageView android:id="@+id/dot6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="left" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> </RelativeLayout> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <ImageView android:id="@+id/dot7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="left" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> </RelativeLayout> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <ImageView android:id="@+id/dot8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_gravity="left" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> </RelativeLayout> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <ImageView android:id="@+id/dot9" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="left" android:background="#ffffff" android:paddingBottom="5dp" android:paddingLeft="1dp"/> </RelativeLayout> </LinearLayout> 

What is the instantiateItem adapter from GridView :

 public Object instantiateItem(ViewGroup container, int position) { GridView gv = new GridView(m_context); gv.setAdapter(new BaseAdapter() { @Override public View getView(int pos, View convertView, ViewGroup parent) { View v; if (convertView == null) { // if it not recycled, initialize some attributes v = mInflater.inflate(R.layout.calendar_month_item, null); } else { v = convertView; } TextView dayView = (TextView) v.findViewById(R.id.date); dayView.setText(pos + ""); return v; } @Override public long getItemId(int p) { return 0; } @Override public Object getItem(int p) { return null; } @Override public int getCount() { return 30; } }); gv.setNumColumns(5); ((ViewPager) container).addView(gv); return gv; } 
+6
source share
3 answers

I looked around a bit and thought I found exactly what you are looking for:

+5
source

What version of Android are you using? This is important because there is a calendar in Android 3.0, there are errors, but they are not so critical.

About your question, if I understood it well. Look at your XML, it contains 11 layouts, and this is just for one element. If you have a lot of them, imagine the amount of work that Android needs to do to inflate all of your elements. And after that, when you sit down, you reuse the elements, and Android needs to update those that are invalid. This is a lot of work. (11 layouts * 30 = 330 layouts that need to be updated or inflated). As the documentation for Android developers says, you should always use as few layouts as possible to wrap your elements as much as possible!

In any case, your approach is incorrect. I can suggest you look at the source code of CalendarView in Android 3+, but give you a hint:

Create a layout for a week, not for every day (for example, in CalendarView). By doing this, Android will only need to update n elements (you will choose how many weeks you want to display at a time), and not 30. This layout should contain 7 views for each day.

I hope you get some idea from this.

+2
source

First of all, your layout is a little weird, as others claim.

  • You really don't need a layout for any additional layout elements.
  • Having a few nested relative or linear layouts if they are not needed will be quite expensive, especially when it is wrapped in a GridView wrapped in a ViewPager.

Secondly, ViewPager and PagerAdapter are a bit complicated.

  • When you have the default number of screens, you will display all three of them at once. If you install it higher, you will display even more views.
  • Make sure you correctly delete the views in destroyItem.
  • Introduce the isViewFromObject method, because otherwise your views will be dropped when you are on the page, which will increase the cost of their recreation.

Riding with @CommonsWare advice is probably a good idea. TraceView is a little tricky to use, but nonetheless it will probably give some hints.

0
source

Source: https://habr.com/ru/post/917754/


All Articles