I have an calendar, so I have to dislay 365 days in 7-in-a-row 52 rows. Every single day has different text. Lot of operation is executing while generating one. So scrolling them is so slow and laggy. How to fix it?
my parent of grid class:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int nr = calendar.get(Calendar.DAY_OF_YEAR);
setContentView(R.layout.activity_main);
calendar.setTime(new Date());
int year = calendar.get(Calendar.YEAR);
boolean p = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
calendar.set(Calendar.DAY_OF_YEAR, 1);
int before = calendar.get(Calendar.DAY_OF_WEEK)-2;
calendar.set(Calendar.DAY_OF_YEAR, 1);
calendar.add(Calendar.YEAR, 1);
calendar.add(Calendar.DAY_OF_YEAR, -1);
int after = calendar.get(Calendar.DAY_OF_WEEK)-2;
final GridView gridView = (GridView) findViewById(R.id.main_grid_calendar);
gridView.setAdapter(new DayAdapter(this, new String[(p?366:365)], before, after));
}
}
my adapter class:
public class DayAdapter extends ArrayAdapter<String> {
private Context context;
private Calendar calendar = Calendar.getInstance();
private final int today = calendar.get(Calendar.DAY_OF_YEAR), before, after, count;
public DayAdapter(Context context, String[] values, int before, int after) {
super(context, R.layout.calendar_day, new String[before + values.length + after]);
this.context = context;
this.before = before;
this.after = after;
this.count = before + values.length + after;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View day = inflater.inflate(R.layout.calendar_day, parent, false);
final TextView date = (TextView) day.findViewById(R.id.dayitem_text_number);
final TextView holiday = (TextView) day.findViewById(R.id.dayitem_text_holiday);
final TextView click = (TextView) day.findViewById(R.id.dayitem_text_more);
SharedPreferences theme = Data.getPreferences(context, Data.Prefs.THEME);
Data.AppColorSet color = Data.getColors(Integer.parseInt(theme.getString(Data.appThemeSetings, "1")));
date.setTextColor(color.foreground);
holiday.setTextColor(color.foreground);
click.setTextColor(color.foreground);
day.setBackgroundColor(color.background);
calendar.set(Calendar.DAY_OF_YEAR, position+1-before);
if (position<before) {
day.setBackgroundColor(Color.GRAY);
} else if (position>=count-after) {
day.setBackgroundColor(Color.GRAY);
} else {
day.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, DayActivity.class);
intent.putExtra("id", position-3);
intent.putExtra("from", "calendar");
context.startActivity(intent);
}
});
}
String d = "" + calendar.get(Calendar.DAY_OF_MONTH);
String m = "" + (1 + calendar.get(Calendar.MONTH));
if (Integer.parseInt(d)<10) {
d = "0" + d;
}
if (Integer.parseInt(m)<10) {
m = "0" + m;
}
if (this.today==position-2) {
RelativeLayout layout = (RelativeLayout) day.findViewById(R.id.dayitem_relative_main);
layout.setBackgroundColor(color.dark?Color.rgb(55, 0, 0):Color.rgb(255, 200, 200));
}
final String today = d + "." + m;
date.setText(today);
String text = HolidayCalendar.getInstance(context).getTexts(today).get(0);
String[] arr = text.split(" ");
String result = "";
final int words = 4;
boolean full = false;
if (arr.length<=words) {
result = text;
full = true;
} else {
for (int i = 0; i<words; i++) {
result += " " + arr[i];
}
result += "...";
}
int number = HolidayCalendar.getInstance(context).getTexts(today).size() - (full?1:0);
if (number != 0) {
click.setText(number + " " + context.getResources().getString(R.string.see_more));
}
holiday.setText(result);
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
day.setLayoutParams(new AbsListView.LayoutParams(width/7, width/4));
return day;
}
}
my parent of grid layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/main_relative_main"
tools:context="${relativePackage}.${activityClass}" >
<GridView
android:id="@+id/main_grid_calendar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/main_adview_bottom_dark"
android:background="#000000"
android:horizontalSpacing="1dp"
android:numColumns="7"
android:verticalSpacing="1dp" >
</GridView>
</RelativeLayout>
my adapter layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dayitem_relative_main"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#FFFFFF"
android:gravity="center" >
<TextView
android:id="@+id/dayitem_text_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="8sp" />
<TextView
android:id="@+id/dayitem_text_more"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="2dp"
android:gravity="center_horizontal"
android:textSize="8sp" />
<TextView
android:id="@+id/dayitem_text_holiday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginBottom="15dp"
android:gravity="center|center"
android:textSize="10sp" />
</RelativeLayout>
EDIT: ViewHolder helped me! Thanks!
The best way and easier one to improve performance easily when displaying lists and grids is to use the new RecyclerView
and, in your case, the GridLayoutManager
. This will improve your performance without modifying large amounts of code. Looks at some documentation on how to implement it here.
Beside that, the lag you are suffering comes from the fact of using findViewById in your getView
method, which is a slow operation repeated many times. The best practice to avoid searching for views all the time is to use the ViewHolder
pattern. Look at the second section in this link.