#android #surfaceview #android-animation
#Android #surfaceview #android-анимация
Вопрос:
я рисую диаграмму элементов, расширяя surfaceview до класса PieChart. теперь я создаю 2 объекта для Piechart и добавляю в ViewFlipper, чтобы перемещаться между этими диаграммами. теперь моя проблема в том, что 2-я диаграмма не видна пользователю, если пользователь переходит ко 2-му просмотру. но вся функциональность 2nd pies работает. я думаю, что это проблема с обновлением surfaceview.
любая помощь по этому вопросу будет заметна. ниже приведен мой класс PieChart.
class MyPieChart extends SurfaceView implements SurfaceHolder.Callback {
@Override
public void onDraw(Canvas canvas) {
if (hasData) {
resetColor();
try {
canvas.drawColor(getResources().getColor(R.color.graphbg_color));
graphDraw(canvas);
} catch (ValicException ex) {
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.i("PieChart", "surfaceChanged");
}
public int callCount = 0;
@Override
public void surfaceCreated(SurfaceHolder holder) {
if ((callCount ) % 2 == 0) {
callCount = 1;
try {
Log.i("PieChart", "surfaceCreated");
mChartThread = new ChartThread(getHolder(), this);
mChartThread.setRunning(true);
if (!mChartThread.isAlive()) {
mChartThread.start();
}
mFrame = holder.getSurfaceFrame();
mOvalF = new RectF(0, 0, mFrame.right, mFrame.right);
} catch (Exception e) {
// No error message required
}
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i("PieChart", "surfaceDestroyed");
boolean retry = true;
callCount = 0;
mChartThread.setRunning(false);
while (retry) {
try {
mChartThread.join();
retry = false;
} catch (InterruptedException e) {
// No error message required
}
}
}
}
class ChartThread extends Thread {
private SurfaceHolder mSurfaceHolder;
private PieChart mPieChart;
private boolean mRefresh = false;
public ChartThread(SurfaceHolder surfaceHolder, PieChart pieChart) {
// Log.i("ChartThread", "ChartThread");
mSurfaceHolder = surfaceHolder;
mPieChart = pieChart;
}
public void setRunning(boolean Refresh) {
// Log.i("ChartThread", "setRunning : " Refresh);
mRefresh = Refresh;
}
@Override
public void run() {
Canvas c;
// Log.i("ChartThread", "run : " mRefresh);
while (mRefresh) {
c = null;
try {
c = mSurfaceHolder.lockCanvas(mPieChart.mFrame);
// c.drawColor(0xFFebf3f5);
synchronized (mSurfaceHolder) {
mPieChart.onDraw(c);
}
} catch (Exception ex) {
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
вот мой flipper.xml
<ViewFlipper
android:id="@ id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout android:id="@ id/pie1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout android:id="@ id/pie2"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
и я вот моя активность
public class ViewFlipperActivity extends Activity {
Button b1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b1 = (Button)findViewById(R.id.submit1);
b1.setOnClickListener(new View.OnClickListener() {
ViewFlipper vflipper=(ViewFlipper)findViewById(R.id.flipper);
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
vflipper.showNext();
}
});
}
и я привязываю диаграммы элементов к линейным описаниям Pie1 и Pie2 в Flipper.
оба элемента pie созданы и вставлены в макеты Pie. теперь, если я перейду ко 2-му представлению в flipper, вместо pie2 будет отображаться Pie1, а все остальные данные и функциональные возможности, которые я получаю, связаны с Pie2. я сомневаюсь, что Pie2 отображается и скрыт под Pie1. может ли кто-нибудь помочь мне в этом с каким-либо решением.
я получил решение по этой проблеме. что вызвало другую проблему со следующими изменениями.
в flipper.xml заменено LinearLayout i в месте просмотра flipper.
<LinearLayout
android:id="@ id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout android:id="@ id/pie1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout >
и в ViewFlipperActivity
public class ViewFlipperActivity extends Activity {
Button b1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b1 = (Button)findViewById(R.id.submit1);
b1.setOnClickListener(new View.OnClickListener() {
LinearLayout vflipper=(LinearLayout)findViewById(R.id.flipper);
LinearLayout pie1=(LinearLayout)findViewById(R.id.pie1);
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
vflipper.setAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));
pie1.removeAllViews();
pie1.addView(PieChart/SurfaceView);
}
});
}
с анимацией и работает нормально, а диаграмма piechart меняется в представлении. но прямоугольник блока становится видимым из surfaceview на секунду при перемещении между диаграммами элементов. может ли кто-нибудь помочь мне в этой проблеме.
Комментарии:
1. я попытался заменить LinearLayout вместо ViewFlipper и попытался анимировать макет анимацией слева направо. в этом случае я также сталкиваюсь с той же проблемой.
2. итак, попробовал удалить и добавить объекты piechart в соответствующие макеты в трассировке с помощью LineaLayout. итак, это сработало для меня.
3. я добавляю этот код. но здесь у меня другая проблема. например, при пролистывании между прямоугольными блоками pie на некоторое время появляется прямоугольник, и анимация происходит нормально.
Ответ №1:
SurfaceView не будет работать должным образом внутри ViewFlipper, поскольку его нельзя правильно анимировать. Вот почему Android 4.0 представляет новый виджет под названием TextureView, который решает эту проблему.
Комментарии:
1. но я продолжаю использовать Android 4.0, моя целевая версия sdk 2.1
Ответ №2:
здесь основная проблема заключается в том, что SurfaceView не может быть анимирован. вот почему ни ViewFlipper, ни анимация макета не могут быть применены к SurfaceView.