今天给大家来讲解一下如何实现QQ侧滑效果,以前我也用过其他的方法,但是我不推荐使用。因为滑动的时候需要计算横坐标的距离,这是滑动会出现三个事件。首先触发的是按下事件,其次触发滑动事件,最后触发松开事件。最主要是当按下的时候容易出现问题,因为如果按下时落点正好在控件上,那触发的是按下的控件的事件还是触发滑动事件呢,这个不好解决,虽然有很多人说通过返回boolean值来确定,但是我发现还是不行。后来通过计算落下和松开的差值,虽然可以,不过还是有点小小的问题,在同事的努力下,我换了另外一种简单的方法。下面我贴出我的工程内容。
效果图如图,由于布局我临时写的不太好看,自己做的项目毕竟不能拿出来,因为属于公司的。自己再写的话太慢了,所以我就拿一个qq的图片给你们看看,我相信大家都知道这个效果。我的目的还是希望大家可以学会,至少能会用都是好的。
这是我的工程结构
好了我下面就会详细介绍
一、首先要导入一个SlidingMenuLib架包,导入架包的时候对着工程右击选择Properties然后选择android,找到add添加工程如图,如果你成功导入架包,那么你可以进入第二步了,如果不行那就可以重启模拟器或者是手机。
二、要建立两个Fragment,这两个Fragment就代表抽屉组件和主界面,切记,导包一定要是v4包,绑定控件时一定要view.findviewById(),好的下面我贴出代码,对于和他相应的布局文件我不贴出来了,布局文件是自己写的。
package com.yuriko.mychouti;
import android.os.Bundle;
import android.support.v4.app.Fragment;//一定要是v4包
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment1 extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment1, null); //R.layout.fragment1是和他相应的布局文件,需要修改的地方也就是这里
return view;
}
}
这是其中一个Fragment,另一个Fragment和他一样。这里我就不做过多解释
三、menu_frame布局文件,这个主要容纳抽屉组件,也就是Fragment2,很简单,就是一个layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/menu_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
四、主要的内容来了,主界面的Activity。我代码注释的也比较详细,这里不做解说,注意继承的是SlidingFragmentActivity这个类,注意导入V4包,因为我就在这里犯了错误,不希望你们再犯。
package com.yuriko.mychouti;
import android.graphics.Canvas;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity;
public class MainActivity extends SlidingFragmentActivity {
//三个Fragment
private Fragment1 f1;
private Fragment2 f2;
private Fragment mContent;
private FragmentManager fm;
private FragmentTransaction ft;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
f1 = new Fragment1();
f2 = new Fragment2();
if (findViewById(R.id.menu_frame) == null) { //上面的那个menu_frame
setBehindContentView(R.layout.menu_frame);
getSlidingMenu().setSlidingEnabled(true);
getSlidingMenu()
.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
} else {
// 添加一个view
View v = new View(this);
setBehindContentView(v);
getSlidingMenu().setSlidingEnabled(false);
getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE);
}
// set the Above View Fragment
if (savedInstanceState != null) {
mContent = getSupportFragmentManager().getFragment(
savedInstanceState, "mContent");
}
//这个就是把f1给mContent
if (mContent == null) {
mContent=f1;
}
//将fragment1加载进主界面,main1是此Activity的一个FrameLayout
getSupportFragmentManager().beginTransaction()
.replace(R.id.main1, mContent).commit();
// 将fragment2加载进menu_frame,类似上面的步骤。
getSupportFragmentManager().beginTransaction()
.replace(R.id.menu_frame, f2).commit();
// 下面代码不需要任何改写,完全可以粘贴过去,注意dimens里面写一个标签。
SlidingMenu sm = getSlidingMenu();
// 在values文件夹下的dimens写一个名字为slidingmenu_offset的dimens标签,具体代码:<dimen name="slidingmenu_offset">60dp</dimen>
//背后的资源id(也就是整个屏幕的宽度-抽屉的宽度)设置为偏移量,这个其实不用解释,英语好的话直接跟进去看源码的解释就好了
sm.setBehindOffsetRes(R.dimen.slidingmenu_offset);
//true就启用褪色,false不启用
sm.setFadeEnabled(false);
//视差滚动的规模
sm.setBehindScrollScale(0.25f);
sm.setFadeDegree(0.25f);
// 设置抽屉的 背景,背景图片自己找,包括另一个Fragment的背景
sm.setBackgroundImage(R.drawable.person_bg);
//下面是逻辑部分,不需要知道为什么,拷贝过去就行
sm.setBehindCanvasTransformer(new SlidingMenu.CanvasTransformer() {
@Override
public void transformCanvas(Canvas canvas, float percentOpen) {
float scale = (float) (percentOpen * 0.25 + 0.75);
canvas.scale(scale, scale, -canvas.getWidth() / 2,
canvas.getHeight() / 2);
}
});
sm.setAboveCanvasTransformer(new SlidingMenu.CanvasTransformer() {
@Override
public void transformCanvas(Canvas canvas, float percentOpen) {
float scale = (float) (1 - percentOpen * 0.25);
canvas.scale(scale, scale, 0, canvas.getHeight() / 2);
}
});
}
}
这是我的主Activity布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<FrameLayout
android:id="@+id/main1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</FrameLayout>
</RelativeLayout>
其实这个很简单,任何监听和初始化都可以在两个Fragment里面写,跟Activity无关。然后在Fragment里面写东西和在Activity里面写一样。
好了这样子就完成了一个QQ的侧滑效果。