随笔: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(); } }
相关文章推荐
- 社交巨头三国杀:微信、WhatsApp、Line到底有啥区别?
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件