我有自定义布局(最终扩展ViewGroup),其中包含2个ImageButtons和1个自定义视图(扩展SurfaceView)。
我的问题是我的图片android:layout_gravity="center"
无效
此外,它甚至没有在xml编辑器中的自动完成中显示
<com.technaim.elecbic.Circle
android:id="@+id/action_circle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
public class Circle extends SurfaceView implements SurfaceHolder.Callback {
private static int PIXELS_TO_REMOVE = 4;
private Paint circlePaint = null;
private int parentWidth;
private int parentHeight;
private int centerX;
private int centerY;
private int radius;
private RadialGradient lockDisplayGradient = null;
private RadialGradient unlockDisplayGradient = null;
public Circle(Context context) {
super(context);
}
public Circle(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
setWillNotDraw(false);
}
public Circle(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
private void initializeMembers() {
View parent = (View) getParent();
circlePaint = new Paint();
circlePaint.setAntiAlias(true);
circlePaint.setDither(true);
parentWidth = parent.getWidth() - PIXELS_TO_REMOVE;
centerX = parentWidth / 2;
parentHeight = parent.getHeight() - PIXELS_TO_REMOVE;
centerY = parentHeight / 2;
radius = getWidth() / 3;
lockDisplayGradient = new RadialGradient(centerX, centerY, radius,
getResources().getColor(R.color.green), getResources()
.getColor(R.color.red), Shader.TileMode.REPEAT);
unlockDisplayGradient = new RadialGradient(centerX, centerY, radius,
getResources().getColor(R.color.red), getResources().getColor(
R.color.green), Shader.TileMode.REPEAT);
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawCircle(centerX, centerY, radius, this.circlePaint);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
initializeMembers();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
}
public void changeToLockDisplay() {
circlePaint.setShader(lockDisplayGradient);
invalidate();
}
public void changeToUnlockDisplay() {
circlePaint.setShader(unlockDisplayGradient);
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
// MUST CALL THIS
setMeasuredDimension(widthSize, heightSize);
}
}
<RelativeLayout 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:gravity="center"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainScreen" >
<com.technaim.elecbic.DragLayer
android:id="@+id/drag_layer"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.technaim.elecbic.Circle
android:id="@+id/action_circle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<ImageButton
android:id="@+id/img_lock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:background="@null"
android:contentDescription="@string/lock"
android:src="@drawable/lock"
android:clickable="false"
android:visibility="invisible"
android:adjustViewBounds="true"/>
<ImageButton
android:id="@+id/img_unlock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:background="@null"
android:contentDescription="@string/unlock"
android:src="@drawable/unlock"
android:clickable="false"
android:visibility="invisible"
android:adjustViewBounds="true"/>
</com.technaim.elecbic.DragLayer>
<Button
android:id="@+id/btn_track_device"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="@string/track_device" />
</RelativeLayout>
更新:
儿童没有任何布局选项
/*
* This is a modified version of a class from the Android Open Source Project.
* The original copyright and license information follows.
*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.technaim.elecbic;
import com.technaim.logic.DragController;
import com.technaim.logic.DragSource;
import com.technaim.logic.DropTarget;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Toast;
/**
* A ViewGroup that coordinates dragging across its dscendants.
*
* <p> This class used DragLayer in the Android Launcher activity as a model.
* It is a bit different in several respects:
* (1) It extends MyAbsoluteLayout rather than FrameLayout; (2) it implements DragSource and DropTarget methods
* that were done in a separate Workspace class in the Launcher.
*/
public class DragLayer extends MyAbsoluteLayout
implements DragSource, DropTarget
{
DragController mDragController;
/**
* Used to create a new DragLayer from XML.
*
* @param context The application's context.
* @param attrs The attribtues set containing the Workspace's customization values.
*/
public DragLayer (Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setDragController(DragController controller) {
mDragController = controller;
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mDragController.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return mDragController.onTouchEvent(ev);
}
@Override
public boolean dispatchUnhandledMove(View focused, int direction) {
return mDragController.dispatchUnhandledMove(focused, direction);
}
/**
*/
// DragSource interface methods
/**
* This method is called to determine if the DragSource has something to drag.
*
* @return True if there is something to drag
*/
public boolean allowDrag () {
// In this simple demo, any view that you touch can be dragged.
return true;
}
/**
* setDragController
*
*/
/* setDragController is already defined. See above. */
/**
* onDropCompleted
*
*/
public void onDropCompleted (View target, boolean success)
{
//toast ("DragLayer2.onDropCompleted: " + target.getId () + " Check that the view moved.");
}
/**
*/
// DropTarget interface implementation
/**
* Handle an object being dropped on the DropTarget.
* This is the where a dragged view gets repositioned at the end of a drag.
*
* @param source DragSource where the drag started
* @param x X coordinate of the drop location
* @param y Y coordinate of the drop location
* @param xOffset Horizontal offset with the object being dragged where the original
* touch happened
* @param yOffset Vertical offset with the object being dragged where the original
* touch happened
* @param dragView The DragView that's being dragged around on screen.
* @param dragInfo Data associated with the object being dragged
*
*/
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo)
{
View v = (View) dragInfo;
/*toast ("DragLayer2.onDrop accepts view: " + v.getId ()
+ "x, y, xO, yO :" + new Integer (x) + ", " + new Integer (y) + ", "
+ new Integer (xOffset) + ", " + new Integer (yOffset));*/
int w = v.getWidth ();
int h = v.getHeight ();
int left = x - xOffset;
int top = y - yOffset;
DragLayer.LayoutParams lp = new DragLayer.LayoutParams (w, h, left, top);
this.updateViewLayout(v, lp);
}
public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo)
{
}
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo)
{
}
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo)
{
}
/**
* Check if a drop action can occur at, or near, the requested location.
* This may be called repeatedly during a drag, so any calls should return
* quickly.
*
* @param source DragSource where the drag started
* @param x X coordinate of the drop location
* @param y Y coordinate of the drop location
* @param xOffset Horizontal offset with the object being dragged where the
* original touch happened
* @param yOffset Vertical offset with the object being dragged where the
* original touch happened
* @param dragView The DragView that's being dragged around on screen.
* @param dragInfo Data associated with the object being dragged
* @return True if the drop will be accepted, false otherwise.
*/
public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo)
{
return true;
}
/**
* Estimate the surface area where this object would land if dropped at the
* given location.
*
* @param source DragSource where the drag started
* @param x X coordinate of the drop location
* @param y Y coordinate of the drop location
* @param xOffset Horizontal offset with the object being dragged where the
* original touch happened
* @param yOffset Vertical offset with the object being dragged where the
* original touch happened
* @param dragView The DragView that's being dragged around on screen.
* @param dragInfo Data associated with the object being dragged
* @param recycle {@link Rect} object to be possibly recycled.
* @return Estimated area that would be occupied if object was dropped at
* the given location. Should return null if no estimate is found,
* or if this target doesn't provide estimations.
*/
public Rect estimateDropLocation(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo, Rect recycle)
{
return null;
}
/**
*/
// More methods
/**
* Show a string on the screen via Toast.
*
* @param msg String
* @return void
*/
} // end class