我在按钮上实现旋转动画,效果很好。
当我把它放在操作栏上时,然后在RequestLayout()
上的窗口调用ListView
的内容中,动画开始丢帧。
由于RequestLayout()
将挂起主线程,因此它有两个解决方案:
ListView
,每40ms释放一次主线程虽然第一个解决方案值得尝试,但我不知道如何实施第二个解决方案。
希望得到你的建议。 ;)
在我的实际项目中,动画是一个简单的旋转动画:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator">
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="500" />
</set>
下面的代码是我用来测试ListView的演示。虽然它与上面的动画无关,但是当我更新ListView的数据时,我可以通过手机提供的GPU开发工具看到android开始丢帧。
在实际项目中,当listview的数据正在更新时,动画会显得滞后。
MainActivity:
public class MainActivity extends Activity {
public static int N_ROW = 200;
private ListView mListView;
private ArrayList<String> mData1 = null;
private ArrayList<String> mData2 = null;
private ArrayList<String> mData3 = null;
private int mCurrData = 1;
private Random r = new Random();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.listView);
/// random, 3-digits test data to display in listview
mData1 = genRandomData(0);
/// longer test data
mData2 = genRandomData(100000);
/// another test data to change content of textView but do not change the content length
mData3 = genRandomData(0);
final ListViewAdapter adapter = new ListViewAdapter(this, R.layout.list_item_name, mData1);
mListView.setAdapter(adapter);
/// change the text using standard notifyDataSetChanged
Button btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrData == 1) {
mCurrData = 3;
adapter.updateData(mData3);
} else {
mCurrData = 1;
adapter.updateData(mData1);
}
adapter.notifyDataSetChanged();
}
});
/// change the text length between long <---> short & invalidate()
Button btn1 = (Button) findViewById(R.id.btn_invalidate);
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrData == 2) {
mCurrData = 1;
adapter.updateData(mData1);
} else {
mCurrData = 2;
adapter.updateData(mData2);
}
refreshVisibleListViewArea();
mListView.invalidate();
}
});
/// change the text using row by row modification & invalidate()
Button btn2 = (Button) findViewById(R.id.btn_invalidate2);
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrData == 3) {
mCurrData = 1;
adapter.updateData(mData1);
} else {
mCurrData = 3;
adapter.updateData(mData3);
}
refreshVisibleListViewArea();
mListView.invalidate();
}
});
/// do nothing but invalidate()
Button btn3 = (Button) findViewById(R.id.btn_invalidate3);
btn3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
refreshVisibleListViewArea();
mListView.invalidate();
}
});
}
private ArrayList<String> genRandomData(int offset) {
ArrayList<String> tmp = new ArrayList<String>();
for (int i = 0; i < N_ROW * 4; ++ i) {
String a = "I_" + r.nextInt(N_ROW * 4 + offset);
tmp.add(a);
}
return tmp;
}
private void refreshVisibleListViewArea() {
int s = mListView.getFirstVisiblePosition();
int e = mListView.getLastVisiblePosition();
for (int i = s; i <= e; ++ i) {
View v = mListView.getChildAt(i - s);
mListView.getAdapter().getView(i, v, mListView);
}
}
}
适配器:
public class ListViewAdapter extends ArrayAdapter<String> {
private ArrayList<String> mData;
private Context mContext;
public ListViewAdapter(Context context, int resource, ArrayList<String> data) {
super(context, resource, data);
mContext = context;
mData = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh = null;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(R.layout.list_item_name, parent, false);
vh = new ViewHolder();
vh.v1 = (TextView) convertView.findViewById(R.id.v1);
vh.v2 = (TextView) convertView.findViewById(R.id.v2);
vh.v3 = (TextView) convertView.findViewById(R.id.v3);
vh.v4 = (TextView) convertView.findViewById(R.id.v4);
convertView.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
if (vh.v1.getText() != mData.get(position * 4)) {
vh.v1.setText(mData.get(position * 4));
}
if (vh.v2.getText() != mData.get(position * 4 + 1)) {
vh.v2.setText(mData.get(position * 4 + 1));
}
if (vh.v3.getText() != mData.get(position * 4 + 2)) {
vh.v3.setText(mData.get(position * 4 + 2));
}
if (vh.v4.getText() != mData.get(position * 4 + 3)) {
vh.v4.setText(mData.get(position * 4 + 3));
}
return convertView;
}
public int getCount() {
return MainActivity.N_ROW;
}
public void updateData(ArrayList<String> data) {
mData = data;
}
class ViewHolder {
TextView v1;
TextView v2;
TextView v3;
TextView v4;
}
}
list_item xml
<?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:orientation="horizontal" >
<TextView
android:id="@+id/v1"
android:layout_width="80dp"
android:layout_height="30dp"
android:background="#f00"
android:ellipsize="none"
android:textSize="16sp" />
<TextView
android:id="@+id/v2"
android:layout_width="80dp"
android:layout_height="30dp"
android:background="#0f0"
android:textSize="16sp" />
<TextView
android:id="@+id/v3"
android:layout_width="80dp"
android:layout_height="30dp"
android:background="#00f"
android:ellipsize="none"
android:textSize="16sp" />
<TextView
android:id="@+id/v4"
android:layout_width="80dp"
android:layout_height="30dp"
android:background="#0ff"
android:ellipsize="none"
android:textSize="16sp" />
</LinearLayout>
答案 0 :(得分:0)
决定将udpate拆分成较小的。
最后,我使用表面视图来实现动画效果。 ;)