Android 自定义相对布局缩放?
我正在尝试制作可以缩放和滚动的自定义RelativeLayout。现在我已经试着达到规模。现在,我已经将自定义相对布局作为另一个相对布局的父布局,该相对布局包含可触摸Imageview作为其子布局。现在,当我缩放父级自定义相对布局时,子级也会缩放,但Imageview的可单击区域会转换,我不知道为什么?当Imageview或布局处于正常位置时,可单击区域位于Imageview上,但一旦布局缩放,可单击区域就会移动?我不知道为什么我会面临可点击的奇怪位置位移 这是密码 我的海关亲戚拉约特Android 自定义相对布局缩放?,android,view,viewgroup,Android,View,Viewgroup,我正在尝试制作可以缩放和滚动的自定义RelativeLayout。现在我已经试着达到规模。现在,我已经将自定义相对布局作为另一个相对布局的父布局,该相对布局包含可触摸Imageview作为其子布局。现在,当我缩放父级自定义相对布局时,子级也会缩放,但Imageview的可单击区域会转换,我不知道为什么?当Imageview或布局处于正常位置时,可单击区域位于Imageview上,但一旦布局缩放,可单击区域就会移动?我不知道为什么我会面临可点击的奇怪位置位移 这是密码 我的海关亲戚拉约特 publ
public class scaleLayout extends RelativeLayout {
private float mScaleFactor=1.0f;
private long lastTouchTime = -1;
public scaleLayout(Context context)
{
super(context);
// setWillNotDraw(false);
}
public scaleLayout(Context context, AttributeSet attrs) {
super(context, attrs);
//setWillNotDraw(false);
// TODO Auto-generated constructor stub
}
/* @Override
public boolean dispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
} */
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
long thisTime = System.currentTimeMillis();
if (thisTime - lastTouchTime < 250) {
// Double tap
mScaleFactor=1.5f;
invalidate();
lastTouchTime = -1;
} else {
// Too slow :)
/* mScaleFactor=1.0f;
invalidate();*/
lastTouchTime = thisTime;
}
}
return super.onInterceptTouchEvent(ev);
}
@Override
protected void dispatchDraw(Canvas canvas) {
// TODO Auto-generated method stub
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(mScaleFactor, mScaleFactor);
super.dispatchDraw(canvas);
canvas.restore();
}
@Override
public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
// TODO Auto-generated method stub
return super.invalidateChildInParent(location, dirty);
}
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
int count = getChildCount();
for(int i=0;i<count;i++){
View child = getChildAt(i);
if(child.getVisibility()!=GONE){
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)child.getLayoutParams();
child.layout(
(int)(params.leftMargin * mScaleFactor),
(int)(params.topMargin * mScaleFactor),
(int)((params.leftMargin + child.getMeasuredWidth()) * mScaleFactor),
(int)((params.topMargin + child.getMeasuredHeight()) * mScaleFactor)
);
}
}
}
这是xml
<com.layoutzooming.scaleLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/gm01"
>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="jhkibnkij"
android:layout_centerInParent="true"
android:textColor="#FFFFFF"
android:textSize="25dp" />
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_marginLeft="500dp"
android:layout_marginTop="250dp"
android:background="#000"
android:src="@drawable/dih01" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_marginLeft="350dp"
android:layout_marginTop="250dp"
android:background="#000"
android:src="@drawable/dih02" />
</RelativeLayout>
</com.layoutzooming.scaleLayout>
父布局的实际值(可伸缩相对布局)增加,因此此相对布局和图像视图都尝试将自己调整到与增加之前相同的位置。缩放之前,它们相对于屏幕有一些位置,现在缩放之后,它们尝试调整到相同的位置。尝试使用线性布局进行缩放我是如何通过添加布局缩放活动中的以下代码
public class LayoutZoomingActivity extends Activity implements OnTouchListener {
ImageView img1; ImageView img2; /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
img1 = (ImageView) findViewById(R.id.imageView1);
img1.setOnTouchListener(this);
img2 = (ImageView) findViewById(R.id.imageView2);
img2.setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
Log.d("b","b");
if(isViewContains(img1, (int)event.getX(), (int)event.getY())) {
img1.setVisibility(View.GONE); }
if(isViewContains(img2, (int)event.getX(), (int)event.getY())) {
img2.setVisibility(View.GONE); }
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.d("onTouchEvent c","c"+(int)event.getX()+","+(int)event.getY());
if(isViewContains(img1, (int)event.getX(), (int)event.getY())) {
img1.setVisibility(View.GONE);
img1.invalidate(); }
if(isViewContains(img2, (int)(event.getX()/scaleLayout.mScaleFactor), (int)(event.getY()/scaleLayout.mScaleFactor))) {
img2.setVisibility(View.GONE);
img2.invalidate(); }
return super.onTouchEvent(event);
}
private boolean isViewContains(View view, int rx, int ry) {
int[] l = new int[2];
view.getLocationOnScreen(l);
int x = l[0];
int y = l[1];
int w = view.getWidth();
int h = view.getHeight();
Log.d("isViewContains::"+x+"::"+y+"::"+w+"::"+h,rx+"::"+ry);
if (rx < x || rx > x + w || ry < y || ry > y + h) {
return false;
}
return true;
} }
public类LayoutZoomingActivity将活动实现扩展到TouchListener上{
ImageView img1;ImageView img2;/**在首次创建活动时调用*/
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
img1=(ImageView)findViewById(R.id.imageView1);
img1.setOnTouchListener(这个);
img2=(ImageView)findViewById(R.id.imageView2);
img2.setOnTouchListener(此);
}
@凌驾
公共布尔onTouch(视图v,运动事件){
//TODO自动生成的方法存根
日志d(“b”、“b”);
if(isViewContains(img1,(int)event.getX(),(int)event.getY()){
img1.setVisibility(View.GONE);}
if(isViewContains(img2,(int)event.getX(),(int)event.getY()){
img2.setVisibility(View.GONE);}
返回false;
}
@凌驾
公共布尔onTouchEvent(运动事件){
//TODO自动生成的方法存根
Log.d(“onTouchEvent c”,“c”+(int)event.getX()+”,“+(int)event.getY());
if(isViewContains(img1,(int)event.getX(),(int)event.getY()){
img1.setVisibility(View.GONE);
img1.invalidate();}
if(isViewContains(img2,(int)(event.getX()/scaleLayout.mScaleFactor),(int)(event.getY()/scaleLayout.mScaleFactor))){
img2.setVisibility(View.GONE);
img2.invalidate();}
返回super.onTouchEvent(事件);
}
私有布尔值isViewContains(视图视图、int rx、int ry){
int[]l=新的int[2];
view.GetLocationOn屏幕(l);
int x=l[0];
int y=l[1];
int w=view.getWidth();
int h=view.getHeight();
Log.d(“isViewContains::“+x+”:“+y+”:“+w+”:“+h,rx+”:“+ry”);
如果(rxx+w | | ryy+h){
返回false;
}
返回true;
} }
请您尝试一下,并根据您的要求进行定制。您的意思是说尝试将自定义线性布局作为父布局?在这个相对论中,Yout和ImageView。。缩放后不会调用onLayout。即使子循环也不会调用,因为只有一个子循环是RelativeLayout。@Pavandroid:如果我将自定义RelativeLayout作为所有ImageView的父循环而不是Relative,为什么我的背景不会得到缩放layout@Pavandroid:相对布局将缩放,这意味着其子级也将调用缩放rite?不需要只在scaleLayout中显示的方法。谢谢它的工作,但我不知道它背后的逻辑?当父母总是要求孩子参加孩子仪式时,怎么能不叫“仅限外出”?请允许我解释一下上述逻辑。。我非常渴望了解这种缩放功能,实际上,仅在创建对象时才调用一次OnlyLayout。在上面的逻辑中,我手动检查onTouchEvent()中是否存在视图。这里的问题是我们可以缩放画布,因此当前视图的位置发生了变化,这与之前的X,Y坐标不同。所以根据安卓系统,它不知道新的转换坐标,但它只知道过去的坐标。所以,仍然在代码中使用过去的坐标。根据我的代码,即使我没有使用onTouch方法,也不会在用户每次触摸屏幕时调用该方法。因此,我使用了onTouchEvent。这里我得到了原始的X和Y坐标。我正在检查onTouchEvent中的点是否存在于视图中,以及它是否存在,我正在做我想做的事情。我正在计算if(isViewContains(img2,(int)(event.getX()/scaleLayout.mScaleFactor),(int)(event.getY()/scaleLayout.mScaleFactor))处新的平移X,Y坐标
public class LayoutZoomingActivity extends Activity implements OnTouchListener {
ImageView img1; ImageView img2; /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
img1 = (ImageView) findViewById(R.id.imageView1);
img1.setOnTouchListener(this);
img2 = (ImageView) findViewById(R.id.imageView2);
img2.setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
Log.d("b","b");
if(isViewContains(img1, (int)event.getX(), (int)event.getY())) {
img1.setVisibility(View.GONE); }
if(isViewContains(img2, (int)event.getX(), (int)event.getY())) {
img2.setVisibility(View.GONE); }
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.d("onTouchEvent c","c"+(int)event.getX()+","+(int)event.getY());
if(isViewContains(img1, (int)event.getX(), (int)event.getY())) {
img1.setVisibility(View.GONE);
img1.invalidate(); }
if(isViewContains(img2, (int)(event.getX()/scaleLayout.mScaleFactor), (int)(event.getY()/scaleLayout.mScaleFactor))) {
img2.setVisibility(View.GONE);
img2.invalidate(); }
return super.onTouchEvent(event);
}
private boolean isViewContains(View view, int rx, int ry) {
int[] l = new int[2];
view.getLocationOnScreen(l);
int x = l[0];
int y = l[1];
int w = view.getWidth();
int h = view.getHeight();
Log.d("isViewContains::"+x+"::"+y+"::"+w+"::"+h,rx+"::"+ry);
if (rx < x || rx > x + w || ry < y || ry > y + h) {
return false;
}
return true;
} }