我正在写一个小动画项目。我遇到的问题是屏幕方向改变,它崩溃了。但我想通了,所以在这里发布完整的代码,有人需要类似的东西。底部的最后一句话解释了我观察到的一个小问题。
在这个项目中,我有一个托管片段的主要活动。并且该片段正在使用自定义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.不确定为什么会发生这种情况。
由于
答案 0 :(得分:0)
我更新了原帖以显示解决方案。