您的位置:首页 > 移动开发 > 微信开发

随笔:tab标签随手势左右滑动的渐变效果,类似微信

2016-06-22 11:22 627 查看

随笔:tab标签随手势左右滑动的渐变效果,类似微信

效果图:



没有借鉴过其他类似效果的项目,自己琢磨出来后才发现原来有其他人写过这个东西,还有很多可以改进的地方,我只是做个暂时记录,看到的童鞋就看看吧

我比较懒,一切都从简,

我也很笨,代码也许有点复杂。

说正事,首先,自定义一个组件当做tab的item使用这个组件有两张图片组成。这个组件布局xml文件里为一个选中图片一个未选中图片,重叠放置,布局里选中图片组件的透明度设为0。(奏是这么懒,加其他文字什么的方法一样一样的),代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/navi_unselected_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/img_description"
android:visibility="visible"/>
<ImageView
android:id="@+id/navi_selected_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/img_description"
android:alpha="0"
android:visibility="visible"/>
</RelativeLayout>


这个组件的java文件吧 加了几个写法,设置状态的两个方法(选中状态和未选中状态,决定哪张图片变透明),还有个是改变两个图片透明度的方法。看代码:

public class NaviTabItemView extends RelativeLayout{
private Context mContext;
private AttributeSet attrs;    //自定义的布局文件的属性
private ImageView unSelectedView;  //未被选中状态的图片控件
private ImageView selectedView; //被选中状态的图片控件

//构造函数
public NaviTabItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext=context;
this.attrs=attrs;
LayoutInflater.from(mContext).inflate(R.layout.navi_tab_item_layout, this, true);

init();
}

public NaviTabItemView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public NaviTabItemView(Context context) {
this(context, null);
}
//初始化控件和图片
public void init(){
unSelectedView=(ImageView) findViewById(R.id.navi_unselected_img);
selectedView=(ImageView) findViewById(R.id.navi_selected_img);
//提取资源图片
TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.NaviTabItemView);
Drawable drawable1 = a.getDrawable(R.styleable.NaviTabItemView_unSelectedImage);
if(drawable1 != null)
unSelectedView.setImageDrawable(drawable1);

Drawable drawable2 = a.getDrawable(R.styleable.NaviTabItemView_selectedImage);
if(drawable2 != null)
selectedView.setImageDrawable(drawable2);
a.recycle();

}
//改变两个图片透明度切换状态 从未被选择->被选
public void setSelected(){
unSelectedView.setAlpha(0f);
selectedView.setAlpha(1f);
}
//改变两个图片透明度切换状态 从被选择->未被选
public void setUnSelected(){
unSelectedView.setAlpha(1f);
selectedView.setAlpha(0f);
}
//改变选中图片透明度 参数:透明度
public void setSelectedAlpha(float alpha){
ViewHelper.setAlpha(selectedView, alpha);
ViewHelper.setAlpha(unSelectedView, 1-alpha);
}

//getters和setters
public ImageView getUnSelectedView() {
return unSelectedView;
}

public void setUnSelectedView(ImageView unSelectedView) {
this.unSelectedView = unSelectedView;
}

public ImageView getSelectedView() {
return selectedView;
}

public void setSelectedView(ImageView selectedView) {
this.selectedView = selectedView;
}
}


这里也看到给这个控件加了自定义的属性attrs.xml里:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 自定义的NaviTabItemView布局属性 -->
<declare-styleable name="NaviTabItemView">
<attr name="unSelectedImage" format="reference" />
<attr name="selectedImage" format="reference" />
</declare-styleable>
</resources>


在主函数布局里这么用:

最外层布局控件里加入以下这句

xmlns:myattrs=”http://schemas.android.com/apk/res/com.zjut.zy.mywork001”

表示标签的组件用法其中一个如下(主布局其他不多说了一毛一样的4个item并列排,上面一个ViewPager):

<com.zjut.zy.mywork001.view.NaviTabItemView
android:id="@+id/navigation_item_1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
myattrs:unSelectedImage="@drawable/navigation_1"
myattrs:selectedImage="@drawable/navigation_1_selected"
android:contentDescription="@string/icon_description" />


然后是4个页面的填充内容,4个Fragment,布局随便定:

public class DemoFragment1 extends Fragment {
private View view;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

this.view=inflater
.inflate(R.layout.demo_fragment_1, container, false);

return view;
}
}


用的是ViewPager+Fragment模式,需要一个适配器:

public class MyFragmentPagerAdapter extends FragmentStatePagerAdapter {

private Context mContext;

private Fragment[] mFragments;

public MyFragmentPagerAdapter(FragmentManager fm, Context context, Fragment[] fragments) {
super(fm);
mContext = context;
mFragments = fragments;
}

@Override
public Fragment getItem(int arg0) {
return mFragments[arg0];
}

@Override
public int getCount() {
return mFragments.length;
}

@Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}

// PagerAdapter只缓存三张要显示的图片,如果滑动的图片超出了缓存的范围,就会调用这个方法,将图片销毁

@Override
public void destroyItem(ViewGroup view, int position, Object object) {

super.destroyItem(view, position, object);

}

@Override
public Object instantiateItem(View container, int position) {
// TODO Auto-generated method stub
return super.instantiateItem(container, position);
}
}


最重要的主函数,填充viewpager,为它加上滑动监听OnPageChangeListener,监听里面做item的渐变处理(使用前面定义的透明度方法)

比较乱的是要先判断滑动的左右方向,看代码注释吧,解释不清了 ,自己都开始凌乱了-_-|||||||

public class DemoMainActivity extends FragmentActivity{
ViewPager mViewPager;
//底部导航标签
NaviTabItemView navigation_item_1,navigation_item_2
,navigation_item_3,navigation_item_4;
List<NaviTabItemView> naviTabItems;
int naviItemSum=0;

private int mCurrentFragment;  //当前页
private MyFragmentPagerAdapter mAdapter;    //viewPager的适配器
private Fragment[] fragments = new Fragment[] {
new DemoFragment1(),
new DemoFragment2(),
new DemoFragment3(),
new DemoFragment4()
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("MYWORK_TAG", "MainActivity.onCreate()");
setContentView(R.layout.demo_activity_main);
initView();
initViewPager();
resetNavigation();

navigation_item_1.setSelected();
}
private void initView(){
mViewPager=(ViewPager) findViewById(R.id.main_view_pager);
navigation_item_1=(NaviTabItemView) findViewById(R.id.navigation_item_1);
navigation_item_1.setOnClickListener(clickNavigation);

navigation_item_2=(NaviTabItemView)  findViewById(R.id.navigation_item_2);
navigation_item_2.setOnClickListener(clickNavigation);

navigation_item_3=(NaviTabItemView)  findViewById(R.id.navigation_item_3);
navigation_item_3.setOnClickListener(clickNavigation);

navigation_item_4=(NaviTabItemView)  findViewById(R.id.navigation_item_4);
navigation_item_4.setOnClickListener(clickNavigation);

//所有NaviTabItemView加入naviTabItems队列
naviTabItems=new ArrayList<NaviTabItemView>();
naviTabItems.add(navigation_item_1);
naviTabItems.add(navigation_item_2);
naviTabItems.add(navigation_item_3);
naviTabItems.add(navigation_item_4);
naviItemSum=naviTabItems.size();
}
private void initViewPager(){
mAdapter=new MyFragmentPagerAdapter(getSupportFragmentManager(), this, fragments);
mViewPager.setOnPageChangeListener(onPageChangeListener);
mViewPager.setAdapter(mAdapter);
mViewPager.setCurrentItem(mCurrentFragment);
mViewPager.setOffscreenPageLimit(1);
}
private OnClickListener clickNavigation=new OnClickListener(){
public void onClick(View v){
if(v==navigation_item_1){
changePage(0);
}else if(v==navigation_item_2){
changePage(1);
}else if(v==navigation_item_3){
changePage(2);
}else if(v==navigation_item_4){
changePage(3);
}
}
};
private void changePage(int currentItem){
if(mViewPager.getCurrentItem()!=currentItem){
mViewPager.setCurrentItem(currentItem, false);
}
}
private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() {
private int lastValue=0; //判断滑动左右方向用
private boolean isRight=false;  //是否向右滑动
private boolean isLeft=false;  //是否向左滑动
@SuppressWarnings("deprecation")
@Override
public void onPageSelected(int arg0) {
isRight=false;
isLeft=false;
mCurrentFragment = arg0;
}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
//      "viewPager-当前页:arg0--偏移百分比:arg1--偏移量:arg2");
//判断左滑右滑
if(!isLeft && !isRight && arg2!=0 && lastValue!=0){
if(arg2-lastValue>0){
//向左滑,arg1、arg2递增
isLeft=true;
isRight=false;

}else if(arg2-lastValue<0  ){
//向右滑,arg1、arg2递减
isRight=true;
isLeft=false;
}
}
lastValue=arg2;

//TabItem的颜色渐变
if(isLeft && arg2>0 && arg0<(naviItemSum-1)){
//向左,arg1增加
//naviTabItems.get(arg0) 被选中至未选中
naviTabItems.get(arg0).setSelectedAlpha(1-arg1);
naviTabItems.get(arg0+1).setSelectedAlpha(arg1);
}else if(isRight && arg2>0 &&  arg0<(naviItemSum-1)){
//向右,arg1减少
//naviTabItems.get(arg0) 未选中至被选中
naviTabItems.get(arg0).setSelectedAlpha(1-arg1);
naviTabItems.get(arg0+1).setSelectedAlpha(arg1);
}
if(arg2==0){
resetNavigation();
naviTabItems.get(arg0).setSelected();
}

}

@Override
public void onPageScrollStateChanged(int arg0) {
}
};

//重置为未选中状态
private void resetNavigation() {
navigation_item_1.setUnSelected();
navigation_item_2.setUnSelected();
navigation_item_3.setUnSelected();
navigation_item_4.setUnSelected();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 微信 标签 前端