使用自定义视图保留片段

时间:2015-10-18 03:47:29

标签: android android-fragments device-orientation

我正在写一个小动画项目。我遇到的问题是屏幕方向改变,它崩溃了。但我想通了,所以在这里发布完整的代码,有人需要类似的东西。底部的最后一句话解释了我观察到的一个小问题。

在这个项目中,我有一个托管片段的主要活动。并且该片段正在使用自定义Bubble视图(Bubble extends View)。

主要活动布局activity_main.xml是:

<?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> 

,主要活动MainActivity.java是:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String tag = "bubble_fragment_tag";
        FragmentManager fm = getFragmentManager();
        if (fm.findFragmentByTag(tag) == null){
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            BubbleFragment bubbleFragment = new BubbleFragment();
            ft.add(R.id.bubble_fragment, bubbleFragment, tag);
            ft.commit();
        }
    }
}

因此,我的主要活动主持一个包含自定义视图的片段。片段布局bubble_fragment.xml是:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    tools:context=".MainActivity"
    android:background="#ffcc33">

    <study.android.dino.testsolar.Bubble
        android:id="@+id/bubbleAnimationView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ff1122"
        android:padding="20dp"/>

    <!-- since parent is FrameLayout, this view will be stacked up in z-order -->
    <LinearLayout
        android:id="@+id/buttonsView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="right|bottom"
        android:layout_margin="10dp">

        <ImageButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"
            android:background="@null"/>
        <ImageButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"
            android:background="@null"/>
        <ImageButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"
            android:background="@null"/>
    </LinearLayout>
</FrameLayout>

,我的BubbleFragment.java文件是: 更新:这是更新了解决问题的BubbleFragment

public class BubbleFragment extends Fragment {

    View view;
    Bubble bubble;
    FrameLayout parent;
    LinearLayout floater;


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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        if (bubble == null){
            view =  inflater.inflate(R.layout.bubble_fragment, container, false); 
            parent = (FrameLayout) view;
        }

        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public void onAttach(Activity activity){
        super.onAttach(activity);

        if (parent != null){
            parent.addView(bubble);
            parent.addView(floater);
        }
    }

    @Override
    public void onDetach(){
        super.onDetach();
        bubble = (Bubble) view.findViewById(R.id.bubbleAnimationView);
        floater = (LinearLayout) parent.findViewById(R.id.buttonsView);
        parent.removeView(bubble);
        parent.removeView(floater);
    }
}

这个片段包含自定义视图Bubble,它只是Canvas上的一个气泡图,在这里并不重要;因此没有完整的代码提供:

public class Bubble extends View {

    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 dx;
    private int dy;
    private int r;
    private int w = 400;
    private int h = 400;
    private int speed = 200;

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

    public Bubble(Context context, AttributeSet attributesSet) {
        super(context, attributesSet);

        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        w = size.x;
        h = size.y;

        x = w/2;
        y = h/2;
        r = 60;
        dx = 1;
        dy = 1;

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

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

    @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(speed);
                    } 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);

        canvas.save();
        // draws bubble on canvas
        canvas.translate(dx, dy);
        bubble.draw(canvas);
        canvas.restore();
    }

    private void moveBubble(){
        dx += 1;
        dy += 1;
        x = x + dx;
        y = y + dy;
        if (bubble.getPaint().getColor() == Color.YELLOW){
            bubble.getPaint().setColor(Color.RED);
        } else {
            bubble.getPaint().setColor(Color.YELLOW);
        }
    }
}

这一切都有效,我的气泡在屏幕上绘制和移动,方向也起作用。我观察到的唯一“小”问题是,根据上面的代码,绘制气泡的速度设置为200ms。然而,当我改变方向时,气泡闪烁得更快,尽管跟踪代码辱骂速度仍然是200.不确定为什么会发生这种情况。

由于

1 个答案:

答案 0 :(得分:0)

我更新了原帖以显示解决方案。