实现qq ipad客户端的对话框平滑移动的效果

今天要写一个android对话框,实现对话框随着手指能够移动,而且当对话框移动到一定程度的时候,能够实现对话框在左右自动隐藏。这个功能比较难,需要系统的学习一下onTouch函数,现在贴出我的源代码:

package com.yelbosh.test;


import java.io.IOException;


import com.yelbosh.test.classes.MyButton;


import android.Manifest;
import android.opengl.Visibility;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.text.Layout;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.support.v4.app.NavUtils;
import android.webkit.*;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;


/**
 * 
 * @author yelbosh
 * 2012-7-15
 */
public class MainActivity extends Activity {
private static final boolean LEFT = true;
private static final boolean RIGHT = false;

private View talkdiv;
private Button photo;
private RelativeLayout rl;
//talkdiv上面的title
private TextView titleBar;
//设置talkidv出现的方向
private boolean talkOrentation = LEFT; 

private int WINDOW_HEIGHT;
private int WINDOW_WIDTH;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rl = (RelativeLayout)findViewById(R.id.mainlayout);
        photo = (Button)findViewById(R.id.myphoto);
        talkdiv = getLayoutInflater().inflate(R.layout.talk, rl,false);
        rl.addView(talkdiv);
        talkdiv.setVisibility(View.INVISIBLE);
        
        titleBar = (TextView)findViewById(R.id.titleBar);
        
        //为titleBar设置监听函数
        titleBar.setOnTouchListener(new View.OnTouchListener() {
//记录初始位置
        int temp;
        int viewLeft;
       
public boolean onTouch(View arg0, MotionEvent event) {
// TODO Auto-generated method stub
int eventaction = event.getAction();
int x = (int)event.getRawX();


switch (eventaction) {
case MotionEvent.ACTION_DOWN:
temp = (int) event.getRawX();//记录起始x坐标
viewLeft = (int)MainActivity.this.talkdiv.getLeft();
break;
case MotionEvent.ACTION_MOVE:
MainActivity.this.talkdiv.layout(viewLeft+x-temp, 0, viewLeft+x-temp+MainActivity.this.talkdiv.getWidth(), MainActivity.this.talkdiv.getHeight());
MainActivity.this.talkdiv.postInvalidate();
break;
case MotionEvent.ACTION_UP:
//根据滑动的距离进行判断
//滑到右边
if((viewLeft + x-temp) > 0.3*MainActivity.this.WINDOW_WIDTH){

//滑向右边
Animation temani = new TranslateAnimation(MainActivity.this.talkdiv.getLeft(),MainActivity.this.talkdiv.getWidth(),0,0);
temani.setDuration(600);
MainActivity.this.talkdiv.startAnimation(temani);
MainActivity.this.talkdiv.setVisibility(View.INVISIBLE);
//使其居中
MainActivity.this.talkdiv.layout(0, 0,MainActivity.this.talkdiv.getWidth(), MainActivity.this.talkdiv.getHeight());
//设置下次从右边出现
MainActivity.this.talkOrentation = MainActivity.this.RIGHT;
}else if((viewLeft + x-temp) < -0.3*MainActivity.this.WINDOW_WIDTH){
//滑向左边
Animation temani = new TranslateAnimation(viewLeft + x-temp,-MainActivity.this.talkdiv.getWidth(),0,0);
temani.setDuration(600);
MainActivity.this.talkdiv.startAnimation(temani);
MainActivity.this.talkdiv.setVisibility(View.INVISIBLE);
MainActivity.this.talkdiv.layout(0, 0,MainActivity.this.talkdiv.getWidth(), MainActivity.this.talkdiv.getHeight());
//设置下次从左边出现
MainActivity.this.talkOrentation = MainActivity.this.LEFT;
}else{
//保持在(0,0)
Animation temani = new TranslateAnimation(viewLeft + x-temp,0,0,0);
temani.setDuration(600);
MainActivity.this.talkdiv.startAnimation(temani);
//使其居中
MainActivity.this.talkdiv.layout(0, 0,MainActivity.this.talkdiv.getWidth(), MainActivity.this.talkdiv.getHeight());
//重绘至中间
MainActivity.this.talkdiv.postInvalidate();
}
break;
}
return true;
}
});
        
        
        WINDOW_HEIGHT = this.getWindowManager().getDefaultDisplay().getHeight();
        WINDOW_WIDTH = this.getWindowManager().getDefaultDisplay().getHeight();
        /**
         * 为按钮设置监听函数
         */
        photo.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {
// TODO Auto-generated method stub
//只有当其不可见的时候我们才执行动画
if(talkdiv.getVisibility() == View.INVISIBLE){
talkdiv.setVisibility(View.VISIBLE);
//判断应该从哪个方向拉出
int temx = MainActivity.this.talkOrentation?-MainActivity.this.talkdiv.getWidth():MainActivity.this.talkdiv.getWidth();
Animation translate = new TranslateAnimation(Animation.RELATIVE_TO_SELF,temx,Animation.RELATIVE_TO_PARENT,0,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0);
translate.setDuration(200);
MainActivity.this.talkdiv.startAnimation(translate);
}
}
});
        
        
        //rl.addView(talkdiv);
        
    }
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    
}

这是整个类所有的源代码,xml文件我就不写了,大家自己慢慢理解吧。


需要注意的几点:

注意onTouch的返回值。改成return true,这样onouch会继续监听

注意取得窗口长宽的方法:

 WINDOW_HEIGHT = this.getWindowManager().getDefaultDisplay().getHeight();

 WINDOW_WIDTH = this.getWindowManager().getDefaultDisplay().getHeight();


这里我是根据窗口的横坐标的值来判断是否应该自动隐藏,并且以窗口的宽的三分之一为边界

注意动画效果的实现,我使用了TranslateAnimation这个类,但是貌似这个动画执行了之后对象又会返回到原来的位置。所以在动画执行完毕后我将其设置为不可见,这样的话我再将其layout中的位置设置为动画执行完毕后想将其放置 的位置这样的话就能达到想要的效果了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值