Android - 交换控件位置:基于LayoutParams的瞬间交换与基于ObjectAnimator动画效果交换

现需要交换两个控件(本文中是两个RelativeLayout),找到了两个方法:

1、使用LayoutParams改变两个layout的属性,即其相对关系(below等),实现位置的交换,但是并没有交换的动画效果,是“瞬间”交换。

2、使用animation交换控件位置,实现了我需要的动画效果。

如下图,交换layoutOne 与layoutTwo 。

一、首先介绍使用LayoutParams的方法。

<span style="font-size:18px;">package com.exchange;

import com.exchange.R;

import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.Toast;

/*
 * Exchange layout with LayoutParams
 * Author : [email protected]
 * Date: 2015/7/15
 */
public class ParamsExchangeActivity extends Activity {

	private Button btnEx;
	private LayoutInflater inflater;
	private RelativeLayout myFirst,mySecond,layoutOne,layoutTwo;

	//set controls' id , the id is random as you like , do NOT use zero
	private int btnExId = 11;
	private int layoutOneId	  = 12;
	private int layoutTwoId   = 13;

	//exchange flag , in order to swap back and forth
	private boolean TAG_firstLayoutTop;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_main);

        btnEx=(Button)findViewById(R.id.button_exchange);

        btnEx.setOnClickListener(new BtnExOnClickListener());

        inflater=getLayoutInflater();  

        TAG_firstLayoutTop = true;

        //init layoutOne
        myFirst = (RelativeLayout) inflater.inflate(
                R.layout.layout_first, null).findViewById(R.id.myFirst);
        layoutOne = (RelativeLayout)findViewById(R.id.LayoutOne);
        layoutOne.removeAllViews();
        layoutOne.addView(myFirst);

        //init layoutTwo
        mySecond = (RelativeLayout) inflater.inflate(
                R.layout.layout_second, null).findViewById(R.id.mySecond);
        layoutTwo = (RelativeLayout)findViewById(R.id.LayoutTwo);
        layoutTwo.removeAllViews();
        layoutTwo.addView(mySecond);

    }

    public class BtnExOnClickListener implements OnClickListener
    {
    	@Override
    	public void onClick(View v){
    		Toast.makeText(getBaseContext(), "exchange!", Toast.LENGTH_SHORT).show();

    		//set id for controls in order to change their Params
    		btnEx.setId(btnExId);
    		layoutOne.setId(layoutOneId);
    		layoutTwo.setId(layoutTwoId);

    		RelativeLayout.LayoutParams params;
    		if(TAG_firstLayoutTop){
    			params = (RelativeLayout.LayoutParams)layoutTwo.getLayoutParams();
    			params.removeRule(RelativeLayout.BELOW);	//remove the exist 'BELOW' rule
    			params.addRule(RelativeLayout.BELOW,11);	//add a new one 'BELOW' rule,below control NO. 11
    			layoutTwo.setLayoutParams(params);

    			params = (RelativeLayout.LayoutParams)layoutOne.getLayoutParams();
    			params.removeRule(RelativeLayout.BELOW);
    			params.addRule(RelativeLayout.BELOW,13);	//below control NO. 13
    			layoutOne.setLayoutParams(params);

    			TAG_firstLayoutTop=false;	// change the flag
    		}else{
    			//vice versa
    			params = (RelativeLayout.LayoutParams)layoutOne.getLayoutParams();
    			params.removeRule(RelativeLayout.BELOW);
    			params.addRule(RelativeLayout.BELOW,11);
    			layoutOne.setLayoutParams(params);

    			params = (RelativeLayout.LayoutParams)layoutTwo.getLayoutParams();
    			params.removeRule(RelativeLayout.BELOW);
    			params.addRule(RelativeLayout.BELOW,12);
    			layoutTwo.setLayoutParams(params);

    			TAG_firstLayoutTop=true;
    		}
    	}

    }
}</span>

二、使用animation交换控件

使用animation交换的方法非常简单:

    	ObjectAnimator.ofFloat(layoutTwo, "TranslationY", -300).setDuration(1000).start();
    	ObjectAnimator.ofFloat(layoutOne, "TranslationY", 300).setDuration(1000).start();
    		

全部代码如下:

package com.exchange;

import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.Toast;

public class AnimExchangeActivity extends Activity {

	private Button btnEx;
	private LayoutInflater inflater;
	private RelativeLayout myFirst,mySecond,layoutOne,layoutTwo;

	private boolean TAG_firstLayoutTop;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_main);

        btnEx=(Button)findViewById(R.id.button_exchange);

        btnEx.setOnClickListener(new BtnExOnClickListener());

        inflater=getLayoutInflater();  

        TAG_firstLayoutTop = true;

        //init layoutOne
        myFirst = (RelativeLayout) inflater.inflate(
                R.layout.layout_first, null).findViewById(R.id.myFirst);
        layoutOne = (RelativeLayout)findViewById(R.id.LayoutOne);
        layoutOne.removeAllViews();
        layoutOne.addView(myFirst);

        //init layoutTwo
        mySecond = (RelativeLayout) inflater.inflate(
                R.layout.layout_second, null).findViewById(R.id.mySecond);
        layoutTwo = (RelativeLayout)findViewById(R.id.LayoutTwo);
        layoutTwo.removeAllViews();
        layoutTwo.addView(mySecond);

    }

    public class BtnExOnClickListener implements OnClickListener
    {
    	@Override
    	public void onClick(View v){
    		Toast.makeText(getBaseContext(), "exchange!", Toast.LENGTH_SHORT).show();

    		if(TAG_firstLayoutTop){
    			//move upward and downward 300
    			ObjectAnimator.ofFloat(layoutTwo, "TranslationY", -300).setDuration(1000).start();
    			ObjectAnimator.ofFloat(layoutOne, "TranslationY", 300).setDuration(1000).start();
    			TAG_firstLayoutTop = false;
    		}else{
    			//back to normal position
    			ObjectAnimator.ofFloat(layoutOne, "TranslationY", 0).setDuration(1000).start();
    			ObjectAnimator.ofFloat(layoutTwo, "TranslationY", 0).setDuration(1000).start();
    			TAG_firstLayoutTop = true;
    		}

    	}

    }
}

源代码下载传送门:稍后补链。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-01 10:32:14

Android - 交换控件位置:基于LayoutParams的瞬间交换与基于ObjectAnimator动画效果交换的相关文章

Android 使用动画效果后的控件位置处理 类似系统通知栏下拉动画

Android的动画的使用,请参考.Android的动画,在设计方面,我有点不太理解,觉得这样搞很怪,因为在控件动画后,即使设置了停留在动画结束时的位置,我们也确实看到了控件停在那个位置,但其实该控件的真实位置还是在原来动画前的那里.举个例子,如果有个Button,你给它设置了动画,让它移动到其他位置,当移动完成后,你会发现,点击Button没有任何效果,而在Button原来的位置,就是动画前的位置点击,明明没有任何控件,却看到了点击Button的效果.不知道Google为什么要这样设计.解决思

android 动态改变控件位置和大小 .

动态改变控件位置的方法: setPadding()的方法更改布局位置. 如我要把Imageview下移200px: ImageView.setPadding( ImageView.getPaddingLeft(),  ImageView.getPaddingTop()+200, ImageView.getPaddingRight(),  ImageView.getPaddingBottom()); 动态改变控件大小的方法: 1.声明控件参数获取对象 LayoutParams lp: 2.获取控件

[Android]界面控件

1. 引用系统自带样式 字体大小 对于能够显示文字的控件(如TextView EditText RadioButton Button CheckBox Chronometer等等),你有时需要控制字体的大小.Android平台定义了三种字体大小. "?android:attr/textAppearanceLarge" "?android:attr/textAppearanceMedium" "?android:attr/textAppearanceSmal

【Android的从零单排开发日记】之入门篇(十三)——Android的控件解析

Android的控件都派生自android.view.View类,在android.widget包中定义了大量的系统控件供开发者使用,开发者也可以从View类及其子类中,派生出自定义的控件. 一.Android的控件结构 Android中有一类重要的控件,称为容器控件,它们派生自View的子类android.view.ViewGroup.每个容器控件都可以作为父控件存在,其中包含若干个子控件,每个子控件占据其父控件的一块区域,统一由父控件进行管理和支配. 交互界面中控件的关系直观上是极其复杂的,

ArcGIS for Android地图控件的5大常见操作

原文地址: ArcGIS for Android地图控件的5大常见操作 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/arcgis_mobile/article/details/7801467   GIS的开发中,什么时候都少不了地图操作.ArcGIS for Android中,地图组件就是MapView,MapView是基于Android中ViewGroup的一个类(参考),也是ArcGIS Runtime SDK for

Android必备:Android UI控件的了解与学习

看这里:Android必备:Android UI控件的了解与学习 由于工作需要,最近一段时间,需要进行Android App开发的学习,之前简单的进行过Android的了解,对于基本的Android环境的搭建等已经有过整理,一个Android App是由一个或多个Activity组成,每一个Activity都是一个UI容器,也就是一个屏幕界面,一个界面的组成则是由一组Android UI控件组成,本篇,我们就来简单的对Android UI控件进行初步的了解和学习. Android UI控件根据其

android课程表控件、悬浮窗、Todo应用、MVP框架、Kotlin完整项目源码

Android精选源码 Android游戏2048 MVP Kotlin项目(RxJava+Rerotfit+OkHttp+Glide) Android基于自定义Span的富文本编辑器 android课程表控件效果源码 Dagger.Clean.MVP框架搭建,快速开发- Andorid 任意界面悬浮窗,实现悬浮窗如此简单 android模仿QQ登录后保存账号和密码效果源码 Android简洁清爽的Todo清单工具(MVP+okhttp3+retrofit+gson) Android优质博客 K

Android常用控件:进度条

各种进度条属于 ProgressBar的子类 Sytle: 水平风格:Horizontal小风格:Small大风格:Large反向风格:Inverse小反向风格:Small.Inverse大反向风格:Large.Inverse 设置style:   style="?android:attr/progressBarStyle..." 主要属性:最大值:max当前进度:progress次要进度值:SecondaryProgress --效果类似于看电影那些缓冲 判断进度条是转圈还是水平的方

Android 标签控件

版本:1.0 日期:2014.7.24 版权:© 2014 kince 转载注明出处 在有的应用中可能需要设置一些标签来方便用去去查询某些信息,比如手机助手或者购物软件之类都会有一些标签.对于软件开发初期来说,直接使用TextView.Button实现是最为简单的一种方式.但是这种方法也有其局限性,比如不能控制换行.耦合性低等缺点.所以除了解决这些问题之外,最好能够封装一个类库出来,方便以后使用. 首先新建一个Tag类, import java.io.Serializable; public c