проблема с отображением surfaceview в viewflipper?

#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.