Android Orientation Change崩溃应用程序

时间:2015-10-13 22:17:16

标签: android fragment android-orientation device-orientation

我有一个简单布局文件的活动,它将创建一个以编程方式创建并添加到其中的片段。该片段没有任何布局文件,因为我以编程方式创建布局,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/bubble_fragment">

</LinearLayout>

My Fragment的onCreateView()是这样的,它将创建布局和类Bubble,它使用Handler(android.os.Handler)对Canvas进行一些绘制:

public class Bubble extends View implements View.OnClickListener {

    private static final boolean BUBBLING = true; //thread is running to draw

    private Paint paint;
    private ShapeDrawable bubble;

    // coordiantes, radius etc
    private int x;
    private int y;
    private int r;
    private int w = 200;
    private int h = 200;

    //handler to invalidate (force redraw on main GUI thread from this thread)
    private Handler handler = new Handler();

    public Bubble(Context context) {
        super(context);
        x = w/2;
        y = h/2;
        r = w/2;

        bubble = new ShapeDrawable(new OvalShape());
        bubble.getPaint().setColor(Color.BLUE);
        bubble.setBounds(0, 0, r, r);

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStrokeWidth(0);
    }

    @Override
    protected void onSizeChanged  (int w, int h, int oldw, int oldh){
        //set bubble parameters (center, size, etc)

        startAnimation();
    }

    public void startAnimation(){
        new Thread(new Runnable() {
            public void run() {
                while (BUBBLING) {
                    moveBubble();

                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {

                    }

                    //update by invalidating on main UI thread
                    handler.post(new Runnable() {
                        public void run() {
                            invalidate();
                        }
                    });
                }
            }
        }).start();
    }


    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // draws bubble on canvas
    }

    private void moveBubble(){
        x = x + 1;
        y = y + 1;
    }

    @Override
    public void onClick(View v) {
        Toast.makeText(this.getContext(), "Tapped on screen", Toast.LENGTH_LONG).show();
    }
}

我正在使用setRetainInstance(true)来保留我的fragmnet状态。一切似乎工作正常,我的绘图工作,刷新自己就好了。但是,在方向更改时,我收到此错误:

E/AndroidRuntime:  Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
     at android.view.ViewGroup.addViewInner(ViewGroup.java:3936)
     at android.view.ViewGroup.addView(ViewGroup.java:3786)
     at android.view.ViewGroup.addView(ViewGroup.java:3727)
     at android.view.ViewGroup.addView(ViewGroup.java:3700)
     at my.study.android.bubble.BubbleFragment.onCreateView(BubbleFragment.java:52)

从我到目前为止所读到的,使用这样的充气机

View v = inflater.inflate(R.layout.camera_fragment, parent, false);

应该解决这个问题,但在我的情况下,我不使用inflater,我动态地为我的片段创建布局。

更新 这是我的清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="my.study.android.bubble" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            >
            <!-- removed this from above to show ActionBar
            android:theme="@style/AppTheme.NoActionBar"> -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

更新2: 我弄清楚它崩溃的原因。我在onCreate()中创建了Bubble。如果我将它移动到onCreateView(),然后在方向上,它不会崩溃。 但是,我的动画不会保留在方向上,这意味着当我更改方向时,气泡会在其初始位置绘制:

public class BubbleFragment extends Fragment {

    Bubble bubble;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        //retain fragment
        setRetainInstance(true);

        //bubble = new Bubble(getActivity()); //THIS WILL CRASH APP, MOVE TO onCreateView instetad
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT,
                100);
        LinearLayout ll = new LinearLayout(getActivity());
        ll.setOrientation(LinearLayout.VERTICAL);

        // instantiate my class that does drawing on Canvas
        bubble = new Bubble(getActivity());
        bubble.setLayoutParams(lp);
        bubble.setBackgroundColor(Color.BLUE);
        ll.addView(bubble);  //if you create bubble in onCreate() this will crash.  Create bubble in onCreateView

        return ll;
    }
}

非常感谢,

0 个答案:

没有答案