package ttc.picture;
import ttc.picture.OnViewChangeListener;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;
public class SwitchLayout extends ViewGroup {
private int mCurScreen ;
private static final int SNAP_VELOCITY = 600;//瞬间速度
private Scroller scroller ;//滚动控制器
private VelocityTracker tracker;//拖动手势的速率跟踪器
private float mLastMotionX;
private Context context;
private OnViewChangeListener onViewChangeListener;//改变imageView
public SwitchLayout(Context context) {
super(context);
this.context = context;
init(context);
}
public SwitchLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init(context);
}
public SwitchLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
init(context);
}
//初始化控件
private void init(Context context) {
mCurScreen = 0;
scroller = new Scroller(context);
}
/**
* 必须要调用的方法
* 目的:当前的view在给自己的子控件指派大小和位置必须要调用的方法
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if(changed){
int childLeft = 0;
int childCount = getChildCount();
for(int i = 0;i < childCount;i++){
View childView = getChildAt(i);
if(childView.getVisibility() != View.GONE){
int childWidth = childView.getMeasuredWidth();
//子控件被填充在父控件中(第二个阶段,第一个阶段为onMeasure,即计算)
childView.layout(childLeft, 0, childLeft + childWidth, childView.getMeasuredHeight());
childLeft += childWidth;//改变左边的起始位置
}
}
}
}
/**
* 计算控件的宽和高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int count = getChildCount();
for(int i = 0;i < count;i++){
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}
//滚到到哪一屏,通过width来控制
scrollTo(mCurScreen*width, 0);
}
public void setOnViewChangeListener(OnViewChangeListener changeListener){
this.onViewChangeListener = changeListener;
}
/**
* 设置自定义控件中的哪个子控件展示在当前屏幕中
* @param pos
*/
public void snapToScreen(int pos) {
System.out.println("当前的位置:" + pos);
if(getScrollX() != (pos * getWidth())){
int destina = pos * getWidth() - getScrollX();//要移动的距离
//开始滚动,从起始地开始,后两个参数为滚动的距离。用坐标来表示
scroller.startScroll(getScrollX(), 0, destina, 0);
mCurScreen = pos;
invalidate();//在主线程中调用这个方法来重绘view,必须在主线程中调用
//改变imageView的显示(根据guide_round.xml可以看出,当状态enabled的
//的时候,用黑点表示,也就是不是当前选中。)
System.out.println("ImageView改变监听" + onViewChangeListener);
if(onViewChangeListener != null){
onViewChangeListener.onViewChange(pos);
}
}
}
@Override
public void computeScroll() {
if(scroller.computeScrollOffset()){
scrollTo(scroller.getCurrX(), scroller.getCurrY());
postInvalidate();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//Return the kind of action being performed --
//one of either ACTION_DOWN, ACTION_MOVE, ACTION_UP, or ACTION_CANCEL.
int action = event.getAction();
/**
* 屏幕上的每一次触摸都会被onTouchEvent捕获到,可以从event得到其x,y的值。
* 特别注意:并且得到的是你当前的触点的x,y坐标的值,也就是说,往左划动的话,
* 你的x的值是变小的。
*/
float x = event.getX();
System.out.println("onTouchEvent--" + x);
switch (action) {
//按下
case MotionEvent.ACTION_DOWN:
if(tracker == null){
tracker = VelocityTracker.obtain();
tracker.addMovement(event);
}
if(!scroller.isFinished())
//防止scroller滚动到最终的x和y的位置
scroller.abortAnimation();
mLastMotionX = x;
System.out.println("mLastMotionX--" + mLastMotionX);
break;
//移动
case MotionEvent.ACTION_MOVE:
int deltalX = (int)(mLastMotionX - x);//开始位置的触点与当前位置的差值
if(canMove(deltalX)){
if(tracker != null){
tracker.addMovement(event);
}
mLastMotionX = x;
//控件滚动的位置
scrollBy(deltalX, 0);
}
break;
//松手
/**
* 往左滑动,因为x是在减小,所以横向速率是负值。
* 往右滑动,因为x是在增大,所以横向速率是正值。
*/
case MotionEvent.ACTION_UP:
int velocityX = 0;
if(tracker != null){
tracker.addMovement(event);
tracker.computeCurrentVelocity(1000);//计算1s滚动的速度
System.out.println("tracker -- "+tracker);
velocityX = (int) tracker.getXVelocity();//得到最终的横向速率
System.out.println("横向速率--" + velocityX);
System.out.println("mCurScreen--" + mCurScreen);
}
//不是第一屏,且是往右滑动
if(velocityX > SNAP_VELOCITY && mCurScreen >0)
snapToScreen(mCurScreen - 1);
//往左滑动,且不是最后一个
else if(velocityX < -SNAP_VELOCITY && mCurScreen < (getChildCount() -1)){
snapToScreen(mCurScreen + 1);
}
//往左滑动,且是最后一个,这里直接finish掉activity
else if(velocityX == 0 && mCurScreen == (getChildCount() -1)){
System.out.println("-----------");
Activity activity = (Activity) context;
Intent intent = new Intent();
intent.setClass(context, ttc.neusoft.ChatRoom.class);
context.startActivity(intent);
activity.finish();
}
//速率不够快是,另一种跳转方式
else{
snapToDestination();
}
if(tracker != null){
tracker.recycle();
tracker = null;
}
break;
}
return true;
}
//滑动到下一屏
private void snapToDestination() {
int screenWidth = getWidth();
//最终滑动的位置超过1\2时,才滚动,否则,destScreen得到将是当前屏的值。
int destScreen = (getScrollX() + screenWidth/2)/screenWidth;
snapToScreen(destScreen);
}
//可滚动的条件
private boolean canMove(int deltalX) {
//getScrollX(),得到触点view在左边的x轴的坐标,它的值是从第一张图到最后一张图算的,
//也就是说:getScrollX()得到的值是 将整个图展开,然后相对的那个x坐标。
if(getScrollX() <= 0 && deltalX <0){//显示的是第一张图,并且是往右划
return false;
}
//显示的是最后一张图并且是往左划
if(getScrollX() >= (getChildCount()-1)*getWidth() && deltalX > 0){
return false;
}
return true;
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
Android之智能聊天软件 (105个子文件)
resources.ap_ 5.85MB
Chat.apk 5.86MB
proguard.cfg 1KB
SwitchLayout.class 5KB
ChatRoom.class 3KB
ChatRoom$2.class 3KB
InsertDialog$3.class 3KB
SwitchActivity.class 2KB
ChatAdapter.class 2KB
InsertDialog.class 2KB
InsertDialog$4.class 2KB
InsertDialog$2.class 2KB
SwitchActivity$MOnClickListener.class 1KB
SwitchActivity$MOnViewChangeListener.class 1KB
R$id.class 1KB
DBHelper.class 1KB
R$drawable.class 1KB
Music.class 974B
InsertDialog$1.class 973B
ChatRoom$1.class 953B
ChatRoom$3.class 949B
ChatEntity.class 796B
ChatRoom$4.class 774B
R$layout.class 529B
R.class 519B
ChatActivity.class 503B
R$string.class 406B
R$raw.class 364B
R$attr.class 319B
OnViewChangeListener.class 163B
.classpath 364B
Thumbs.db 68KB
Thumbs.db 8KB
Thumbs.db 6KB
Thumbs.db 5KB
classes.dex 21KB
SwitchLayout.java 7KB
InsertDialog.java 5KB
ChatRoom.java 4KB
R.java 4KB
SwitchActivity.java 3KB
ChatAdapter.java 2KB
Music.java 794B
DBHelper.java 627B
ChatEntity.java 557B
ChatActivity.java 335B
OnViewChangeListener.java 106B
chtt.mp3 4.65MB
a.png 359KB
a.png 356KB
d.png 308KB
d.png 265KB
b.png 186KB
b.png 182KB
e.png 151KB
c.png 129KB
add2.png 55KB
chat.png 11KB
chatpic.png 11KB
add.png 10KB
ic_launcher.png 9KB
ic_launcher.png 8KB
ic_launcher.png 7KB
ic_launcher.png 7KB
robot.png 4KB
line.png 4KB
robot.png 4KB
send.png 4KB
line.png 3KB
quitiocn.png 3KB
humen.png 3KB
humen.png 3KB
quitiocn.png 3KB
teach.png 3KB
back.png 3KB
teach.png 2KB
back.png 2KB
ic_launcher.png 2KB
ic_launcher.png 2KB
button2.png 1KB
button1.png 1KB
input_normal..png 539B
chat_right.png 509B
input_normal..png 483B
chat_left.png 463B
chat_right.png 366B
chat_left.png 351B
tabbar_bg_press.png 295B
tabbar_bg_press.png 195B
guide_dot_white.png 192B
guide_dot_black.png 192B
guide_dot_white.png 192B
guide_dot_black.png 192B
org.eclipse.jdt.core.prefs 208B
.project 840B
project.properties 361B
adddialog.xml 3KB
main.xml 3KB
chat.xml 2KB
list.xml 2KB
共 105 条
- 1
- 2
资源评论
- zzgwxf2013-07-09很不错的例子,对我很有帮助
- 苃灬潙2013-07-02不错,功能差不多都实现了,只不过对话内容需要自己添加,不怎么智能。谢谢分享!
Timy1010
- 粉丝: 14
- 资源: 8
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功