我有以下类生成日历视图。我不太喜欢内置的那个,并试图更好地控制它的外观。然而,渲染新UI(例如,在滑动时)需要1-2秒来绘制。有什么地方可以加快速度吗?我正在对HTC One S(2012款)进行测试
应该相对简单易懂:
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import org.joda.time.LocalDate;
import java.util.ArrayList;
public class Calendar extends AppCompatActivity {
private LocalDate _currentSelectedDate = new LocalDate();;
private LocalDate _today = new LocalDate();;
private float x1 = 0;
private float x2 = 0;
private float y1 = 0;
private float y2 = 0;
private TableLayout _tableLayout;
private RelativeLayout _relativeLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calendar);
_relativeLayout = (RelativeLayout) findViewById(R.id.calendarLayout);
recreateUI(_currentSelectedDate.getYear(), _currentSelectedDate.getMonthOfYear());
}
@Override
public boolean onTouchEvent(MotionEvent touchevent)
{
switch (touchevent.getAction())
{
case MotionEvent.ACTION_DOWN:
{
x1 = touchevent.getX();
y1 = touchevent.getY();
break;
}
case MotionEvent.ACTION_UP:
{
x2 = touchevent.getX();
y2 = touchevent.getY();
// up
if (y1 > y2)
{
_currentSelectedDate = _currentSelectedDate.plusMonths(1);
recreateUI(_currentSelectedDate.getYear(), _currentSelectedDate.getMonthOfYear());
}
// down
if (y1 < y2)
{
_currentSelectedDate = _currentSelectedDate.minusMonths(1);
recreateUI(_currentSelectedDate.getYear(), _currentSelectedDate.getMonthOfYear());
}
break;
}
}
return false;
}
private void recreateUI(int year, int month)
{
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
_tableLayout = new TableLayout(this);
_tableLayout.setLayoutParams(lp);
_tableLayout.setStretchAllColumns(true);
_relativeLayout.removeAllViews();
_relativeLayout.addView(_tableLayout);
LocalDate date = new LocalDate().withYear(year).withMonthOfYear(month).dayOfMonth().withMinimumValue();
LocalDate last = date.dayOfMonth().withMaximumValue();
addMonthNameToUi(date);
addDaysNamesToUi();
addDayNumberssToUi(date, last);
}
private void addMonthNameToUi(LocalDate date) {
TableRow row = new TableRow(this);
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.FILL_PARENT);
params.span = 7;
TextView t = new TextView(this);
t.setLayoutParams(params);
t.setGravity(Gravity.CENTER);
t.setTypeface(null, Typeface.BOLD);
t.setText(date.toString("MMM yyyy"));
row.addView(t);
float d = getResources().getDisplayMetrics().density;
int margin = (int)(20 * d);
ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) t.getLayoutParams();
mlp.setMargins(mlp.leftMargin, mlp.topMargin, mlp.rightMargin, margin);
_tableLayout.addView(row);
}
private void addDaysNamesToUi() {
TableRow dayNameRow = new TableRow(this);
addMonth(dayNameRow, "Mon");
addMonth(dayNameRow, "Tue");
addMonth(dayNameRow, "Wed");
addMonth(dayNameRow, "Thu");
addMonth(dayNameRow, "Fri");
addMonth(dayNameRow, "Sat");
addMonth(dayNameRow, "Sun");
_tableLayout.addView(dayNameRow);
}
private void addDayNumberssToUi(LocalDate date, LocalDate last) {
TableRow row = null;
int columnsCount = 0;
boolean firstRow = true;
while (date.isBefore(last) || date.isEqual(last)) {
if (columnsCount == 0) {
row = new TableRow(this);
_tableLayout.addView(row, new TableLayout.LayoutParams(TableLayout.LayoutParams.FILL_PARENT, TableLayout.LayoutParams.FILL_PARENT, 1.0f));
// blank columns for days not at the start of month
if (firstRow) {
firstRow = false;
int i = 1;
for (; i < date.getDayOfWeek(); i++) {
addDayNumberToRow(row, date, "");
}
columnsCount += i - 1;
date.plusDays(i - 1);
}
}
addDayNumberToRow(row, date, String.valueOf(date.getDayOfMonth()));
date = date.plusDays(1);
columnsCount++;
if (columnsCount == 7)
columnsCount = 0;
}
while (row.getChildCount() < 7)
addDayNumberToRow(row, date, "");
}
private void addMonth(TableRow row, String month)
{
TextView t = new TextView(this);
t.setText(month);
t.setGravity(Gravity.CENTER);
t.setTypeface(null, Typeface.BOLD);
row.addView(t);
}
private void addDayNumberToRow(TableRow row, final LocalDate date, String text)
{
TextView v = new TextView(this);
v.setText(text);
v.setGravity(Gravity.CENTER);
v.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.FILL_PARENT, 1.0f));
if (date.getDayOfMonth() == _today.getDayOfMonth() && date.getMonthOfYear() == _today.getMonthOfYear() && date.getYear() == _today.getYear()) {
v.setTypeface(v.getTypeface(), Typeface.BOLD);
v.setTextSize(v.getTextSize() + 1);
}
ShapeDrawable border = new ShapeDrawable(new RectShape());
border.getPaint().setStyle(Paint.Style.STROKE);
border.getPaint().setColor(Color.BLACK);
v.setBackground(border);
row.addView(v);
}
}
答案 0 :(得分:0)
你的&#34; recreateUI&#34;方法做了很多像创建新视图的东西。避免通过重用已创建的对象来创建新对象。
通常日历视图非常复杂。您很可能不会以这种方式使用多个视图来实现平滑帧率。你必须写自定义视图,女巫会画自己。
答案 1 :(得分:-1)
事实证明,在调试模式下运行应用程序会导致大量减速 - 正常运行会导致性能可接受。