首页 > 其他分享 >拖动一个控件在另一个控件(layout)上,并固定位置在几个位置显示

拖动一个控件在另一个控件(layout)上,并固定位置在几个位置显示

时间:2023-04-07 10:04:22浏览次数:50  
标签:控件 layout int 位置 getWidth width animation btn left





实现效果: 鼠标拖动btn SSS,SSS在水平的layout上移动。 当鼠标抬起 响应UP事件。SSS会自动移动到距离其最近的Btn上,与其重合。即SSS如图只存在五个固定的显示位置。



SSS响应setOnTouchListener事件。



在MotionEvent.ACTION_UP事件中,调用TranslateAnimation动画效果,将其从UP事件位置移动到最近的btn所在位置。



即在UP事件中,响应函数:


private void setPosition() {
            int positionPixel = (touchBtn.getLeft()+touchBtn.getRight())/2;
            int positionIndex = (positionPixel)/btn[1].getWidth();
            int toPosition = positionIndex*btn[1].getWidth()+touchBtn.getWidth()/2;        
            touchBtn.layout(positionIndex*btn[1].getWidth(), touchBtn.getTop(),positionIndex*btn[1].getWidth()+touchBtn.getWidth(), 
                            touchBtn.getBottom());            
            MoveAction = new TranslateAnimation(positionPixel - toPosition,0,0,0);
            MoveAction.setDuration(500);
            touchBtn.startAnimation(MoveAction);
//            touchBtn.invalidate();            
        }




动画效果,将其移动到最近位置上



或者也可以这样计算:


/**
*获得最佳停留位置
*/
private void setBestPosition(View v) {
		int width=v.getWidth();
        int left = v.getLeft();
        int selectedPosition = Math.round(1.0F*left/width);//四舍五入  
        int toPosition = selectedPosition*width;  
        v.layout(selectedPosition*width, v.getTop(),  
                selectedPosition*width+width, v.getBottom());  
        TranslateAnimation animation = new TranslateAnimation(left-toPosition,0,0,0);  
        animation.setInterpolator(new LinearInterpolator());    
        animation.setDuration(400);  
        animation.setFillAfter(true);    
        v.startAnimation(animation); 
//        v.invalidate();
    }




全代码:


public class App extends Activity{
	private static final String tag="App";
	private Context context;
	private FrameLayout container;
	private Button btn;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        context=this;
        
        container=(FrameLayout)findViewById(R.id.container);
        
        btn=(Button)findViewById(R.id.btn);
        btn.setBackgroundResource(R.drawable.tabswitcher_short);
        btn.setOnTouchListener(touchLisener);
        btn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Log.i(tag,"btn clicked");
				
			}
		});
    }
    
    @Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
	}

	OnTouchListener touchLisener=new OnTouchListener() {
    	int lastX, lastY;
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			// TODO Auto-generated method stub
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				lastX = (int) event.getRawX();
                lastY = (int) event.getRawY();
				break;
			case MotionEvent.ACTION_MOVE:
				int dx = (int) event.getRawX() - lastX;  
//				int dy = (int) event.getRawY() - lastY;  
                int dy = 0;  

                int left = v.getLeft() + dx;  
                int top = v.getTop() + dy;  
                int right = v.getRight() + dx;  
                int bottom = v.getBottom() + dy;  

                if (left < 0) {  
                    left = 0;  
                    right = left + v.getWidth();  
                }  

                if (right > container.getMeasuredWidth()) {  
                    right = container.getMeasuredWidth();  
                    left = right - v.getWidth();  
                }  

                if (top < 0) {  
                    top = 0;  
                    bottom = top + v.getHeight();  
                }  

                if (bottom > container.getMeasuredHeight()) {  
                    bottom = container.getMeasuredHeight();  
                    top = bottom - v.getHeight();  
                }  

                v.layout(left, top, right, bottom);  

                lastX = (int) event.getRawX();  
                lastY = (int) event.getRawY();
				break;
			case MotionEvent.ACTION_UP:
				setBestPosition(v);
				break;

			default:
				break;
			}
			return false;
		}
	};
	
	private void setBestPosition(View v) {
		int width=v.getWidth();
        int left = v.getLeft();
        int selectedPosition = Math.round(1.0F*left/width);//四舍五入  
        int toPosition = selectedPosition*width;  
        v.layout(selectedPosition*width, v.getTop(),  
                selectedPosition*width+width, v.getBottom());  
        TranslateAnimation animation = new TranslateAnimation(left-toPosition,0,0,0);  
        animation.setInterpolator(new LinearInterpolator());    
        animation.setDuration(400);  
        animation.setFillAfter(true);    
        v.startAnimation(animation); 
//        v.invalidate();
    }
}


布局


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 	xmlns:app="http://schemas.android.com/apk/res/com.ql.app"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="TEST DRAG"
		android:textSize="20sp"
		/>
		 <FrameLayout android:id="@+id/container"
		 android:layout_width="fill_parent"
	    android:layout_height="fill_parent"
	    android:layout_weight="1"
	    >
		    <Button android:id="@+id/btn"
		    android:layout_width="80dp"
			android:layout_height="wrap_content"
			android:text="drag me!"
		    />
	    </FrameLayout>
	    <EditText 
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    />
</LinearLayout>



但是这样有个问题:当点击EditText弹出输入法的时候,那个拖动条会回到初始的位置,这是何故?

  • 拖动一个控件在另一个控件(layout)上,并固定位置在几个位置显示_ide

  • 大小: 8.5 KB
  • 查看图片附件

标签:控件,layout,int,位置,getWidth,width,animation,btn,left
From: https://blog.51cto.com/u_5454003/6174595

相关文章

  • 一个类似Tabs的控件SegmentControl
    packagecom.ql.view;importjava.util.HashMap;importjava.util.Map;importandroid.content.Context;importandroid.graphics.Color;importandroid.util.AttributeSet;importandroid.view.MotionEvent;importandroid.view.View;importandroid.widget.Linea......
  • CSS常用背景属性(背景颜色、背景图片、背景平铺、背景位置、背景附着、背景色半透明、
    本博文记录CSS中比较常用的背景属性,包括背景颜色:background-color、背景图片:background-image、背景平铺:background-repeat、背景位置:background-position和背景附着:background-attachment。同时记录了背景色半透明的写法以及背景属性复合写法。1常用背景属性属性描述使用......
  • SwipeRefreshLayout和ListView的EmptyView共存冲突的问题
    SwipeRefreshLayout是android官方的下拉刷新控件;它内部有且只能有一个子控件;当一个ListView嵌入到它内部时,就不能为ListView带一个EmptyView了;于是很自然的想到将ListView和EmptyView纳入到一个父控件中;典型的像下面这样的布局:<android.support.v4.......
  • 缓存式的ViewPager&和其他手势控件冲突的解决办法
    一般来说ViewPager如果有很多页的话,会加载它的上一页,当前页和下一页,当从n页以后再想回到第一页,就会再加载一次,这样第一页很多操作后的数据就会被重置,原因是在PagerAdapter的destroyItem经常会移除View,类似下面这样的代码:@Overridepublicvoiddest......
  • 高效快捷解决一个TextView显示多种字体的控件SpannableTextView
    这个控件本人强烈推荐,它会使得布局非常的简单且高效;下面这个布局如果是你,你会用多少层?多少控件生成?告诉你吧,一个SpannableTextView控件就搞定了!它把TextView和Spannable封装在了一起,可以在一个TextView中显示不同的字体颜色,大小,背景色等;它支持如下样式:*......
  • CoordinatorLayout之Behavior使用
    importandroid.animation.Animator;importandroid.content.Context;importandroid.support.design.widget.CoordinatorLayout;importandroid.support.v4.view.ViewCompat;importandroid.support.v4.view.animation.FastOutSlowInInterpolator;importandroid.util.......
  • LinearLayout增加divider分割线
    在android3.0及后面的版本在LinearLayout里增加了个分割线android:divider="@drawable/shape"<!--分割线图片-->android:showDividers="middle|beginning|end"<!--分割线位置-->分割线如果是图片那就直接使用图片就行,如果要使用颜色就必须使用shape来显......
  • LoadMoreListView+SwipeRefreshLayout(分页下拉)基本结构
    一切为了快速迭代importjava.util.ArrayList;importorg.json.JSONObject;importandroid.animation.ObjectAnimator;importandroid.os.Bundle;importandroid.support.v4.widget.SwipeRefreshLayout;importandroid.util.Log;importandroid.vie......
  • StepsView显示步骤执行情况的控件
    显示步骤执行情况的控件,在某些情况下,还是非常有用的。<com.anton46.stepsview.StepsViewxmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/stepsView0"android:layout_width="match_parent"......
  • 使用TableLayout应该注意的地方
    4.0之后推荐使用GridLayout代替TableLayout详情见:浅谈android4.0开发之GridLayout布局TableLayout和我们平时在网页上见到的Table有所不同,TableLayout没有边框的,它是由多个TableRow对象组成,每个TableRow可以有0个或多个单元格,每个单元格就是一个View。......