android模仿移动MM Tab 点击 背景 滑动效果
16lz
2021-01-26
http://ouyangfeng521.iteye.com/blog/1112905
在玩MM时看到里面的tab 很酷 就学着做了一个
效果如下:
上代码 现在我把他搞成了一个控件了 用法跟ListView 差不多
控件类:
Java代码
- packagecom.test.scrolltab.control;
- importjava.util.HashMap;
- importandroid.content.Context;
- importandroid.content.res.TypedArray;
- importandroid.graphics.Canvas;
- importandroid.graphics.drawable.Drawable;
- importandroid.util.AttributeSet;
- importandroid.util.Log;
- importandroid.view.LayoutInflater;
- importandroid.view.View;
- importandroid.widget.LinearLayout;
- importandroid.widget.TextView;
- importcom.test.scrolltab.R;
- publicclassScrcoolTabextendsLinearLayout{
- privateinttop,bottom;//该布局的top与bottom
- privateLayoutInflatermInflater;//控件xml解析器
- privateOnItemClickListenerclickListener;//点击事件
- privateintdefaultTab;//默认选中第几个
- privatebooleanmove=false;//标识是否可以移动,主要为了实现一个项点击后,用户不能点击第二个
- privateHashMap<Integer,Integer[]>childPointCache=newHashMap<Integer,Integer[]>();
- intchildWidth=0;//因为要控件居中,所以计算出每个控件可以有多少宽度
- privateintgleft,currentwidth,currentleft;//上一个选中项的左坐标当前点击的控件的宽度当前点击的控件的左坐标
- privateInteger[]current={0,0};//tab背景的坐标
- privateDrawabletabpictrue;//tab移动的背景图片
- privateinttabpicpadding;//tab背景图片大于控件多少
- privateintmoveunit;//tab图片第次移动多少
- privateintduration;//移动速度
- publicScrcoolTab(Contextcontext,AttributeSetattrs){
- super(context,attrs);
- mInflater=(LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- TypedArraya=context.obtainStyledAttributes(attrs,R.styleable.ScrcoolTab);
- finalintN=a.getIndexCount();
- for(inti=0;i<N;i++){
- intattr=a.getIndex(i);
- switch(attr){
- caseR.styleable.ScrcoolTab_tabpictrue:
- tabpictrue=(Drawable)a.getDrawable(i);
- break;
- caseR.styleable.ScrcoolTab_tabpicpadding:
- tabpicpadding=a.getDimensionPixelSize(i,5);
- break;
- caseR.styleable.ScrcoolTab_moveunit:
- moveunit=a.getDimensionPixelSize(i,5);
- break;
- caseR.styleable.ScrcoolTab_duration:
- duration=a.getInt(i,100);
- break;
- }
- }
- Log.i("ScrcoolTab","construt");
- }
- @Override
- protectedvoidonDraw(Canvascanvas){
- super.onDraw(canvas);
- if(!isDrawItem())return;
- tabpictrue.setBounds(current[0]-tabpicpadding,top,current[0]+currentwidth+tabpicpadding,bottom);
- tabpictrue.draw(canvas);
- }
- @Override
- protectedvoidonLayout(booleanchanged,intl,intt,intr,intb){
- Log.i("ScrcoolTab","onLayout");
- super.onLayout(changed,l,t,r,b);
- top=t;
- bottom=b;
- intcount=getChildCount();
- if(0==count)return;
- intw=r-l;
- childWidth=w/count;
- Viewv=null;
- Integer[]points=null;
- for(inti=0;i<count;i++){
- v=getChildAt(i);
- points=scalcChildPoint(v,i);
- v.layout(points[0],((bottom-top)-v.getHeight())/2,points[1],((bottom-top)-v.getHeight())/2+v.getHeight());
- v.setTag(newInteger(i));
- v.setOnClickListener(newOnClickListener(){
- @Override
- publicvoidonClick(Viewv){
- if(!move){
- move=true;
- itemOnclick(v,((Integer)v.getTag()).intValue());
- }
- }
- });
- }
- //setdefaulttab
- ViewmDefaultTab=getChildAt(defaultTab);
- if(null!=mDefaultTab){
- itemOnclick(v,defaultTab);
- }
- }
- publicsynchronizedvoidupdate(Viewv,intposition){
- Log.i("ScrcoolTab","update");
- current=childPointCache.get(newInteger(position));
- currentleft=current[0];
- currentwidth=v.getWidth();//得到当前点击的控件的宽度
- //如果重复点一个项,则不会移动
- if(gleft==current[0]){
- move=false;//下一个点击可以移动
- return;
- }
- clickListener.onItemClickListener(v,((Integer)v.getTag()).intValue());//通知设置监听
- Log.i("ScrcoolTab","tabmoved");
- defaultTab=position;
- finalbooleanpathleft=gleft>current[0]?true:false;//判断是向左还是向右
- finalintnum=Math.abs((gleft-current[0])/moveunit);
- inti=0;
- while(i<num){
- if(pathleft){
- gleft=gleft-moveunit;
- current[0]=gleft;
- }else{
- gleft=gleft+moveunit;
- current[0]=gleft;
- }
- try{
- Thread.sleep(duration);
- }catch(InterruptedExceptione){
- e.printStackTrace();
- }
- Log.i("ScrcoolTab","Thread:left"+current[0]);
- postInvalidate();
- i++;
- }
- //校正因为除数可能有精度损失
- if(gleft!=currentleft){
- current[0]=currentleft;
- postInvalidate();
- }
- gleft=current[0];
- move=false;
- }
- /**
- *当点击一项时,移动背景坐标
- *@paramv
- */
- publicsynchronizedvoiditemOnclick(finalViewv,finalintposition){
- Log.i("ScrcoolTab","itemOnclickposition:"+position);
- newThread(newRunnable(){
- @Override
- publicvoidrun(){
- update(v,position);
- }
- }).start();
- }
- /**
- *设置数据适配器
- *@paramadapter
- */
- publicvoidsetAdapter(ScrcoolTabAdapteradapter){
- Log.i("ScrcoolTab","setAdapter");
- if(null!=adapter&&0!=adapter.getResource()&&null!=adapter.getData()){
- Viewview=null;
- for(Stringstr:adapter.getData()){
- view=mInflater.inflate(adapter.getResource(),this,false);
- if(viewinstanceofTextView)((TextView)view).setText(str);
- this.addView(view);
- }
- }
- }
- /**
- *计算每个子控件的坐标
- *@paramview
- *@paramposition
- *@return
- */
- publicInteger[]scalcChildPoint(Viewview,intposition){
- Integer[]points=newInteger[2];
- points[0]=childWidth*position+(childWidth-view.getWidth())/2;
- points[1]=points[0]+view.getWidth();
- Log.i("ScrcoolTab","scalcChildPointposition:"+position+"left:"+points[0]+"right:"+points[1]);
- childPointCache.put(newInteger(position),points);
- returnpoints;
- }
- /**
- *是否画背景图片taab
- *@return
- */
- privatebooleanisDrawItem(){
- if(current[0]>0)returntrue;
- elsereturnfalse;
- }
- /**
- *设置默认选中
- *@paramtab
- */
- publicvoidsetDefaultTab(inttab){
- Log.i("ScrcoolTab","setDefaultTab");
- this.defaultTab=tab;
- }
- @Override
- protectedvoidonAttachedToWindow(){
- super.onAttachedToWindow();
- Log.i("ScrcoolTab","onAttachedToWindow");
- }
- /**
- *得到当前选中的项
- *@return
- */
- publicintgetFocus(){
- returndefaultTab;
- }
- /**
- *当点一项时调用事件
- *@paramclickListener
- */
- publicvoidsetOnItemClickListener(OnItemClickListenerclickListener){
- this.clickListener=clickListener;
- }
- /**
- *事件接口
- *
- */
- publicinterfaceOnItemClickListener{
- voidonItemClickListener(Viewv,intposition);
- }
- }
控件适配器类:
Java代码- packagecom.test.scrolltab.control;
- publicclassScrcoolTabAdapter{
- privateintresource;
- privateString[]data;
- publicintgetResource(){
- returnresource;
- }
- publicvoidsetResource(intresource){
- this.resource=resource;
- }
- publicString[]getData(){
- returndata;
- }
- publicvoidsetData(String[]data){
- this.data=data;
- }
- publicScrcoolTabAdapter(intresource,String[]data){
- super();
- this.resource=resource;
- this.data=data;
- }
- }
用法:
xml 布局文件:
Xml代码- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:control="http://schemas.android.com/apk/res/com.test.scrolltab"
- android:orientation="vertical"android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <com.test.scrolltab.control.ScrcoolTab
- android:id="@+id/scrcoolTab"android:layout_height="wrap_content"
- android:layout_width="fill_parent"android:gravity="center_vertical"
- control:tabpictrue="@drawable/bg_item_t"android:background="@drawable/bg_t"
- control:tabpicpadding="5dip"control:moveunit="15dip"control:duration="50">
- </com.test.scrolltab.control.ScrcoolTab>
- </LinearLayout>
一个tab的布局:
Xml代码- <?xmlversion="1.0"encoding="utf-8"?>
- <TextViewandroid:layout_width="wrap_content"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="wrap_content"style="@style/text_style"
- android:onClick="itemOnclick"/>
activity调用代码:
Java代码- packagecom.test.scrolltab;
- importandroid.app.Activity;
- importandroid.os.Bundle;
- importandroid.os.Process;
- importandroid.view.View;
- importandroid.view.ViewParent;
- importcom.test.scrolltab.control.ScrcoolTab;
- importcom.test.scrolltab.control.ScrcoolTabAdapter;
- importcom.test.scrolltab.control.ScrcoolTab.OnItemClickListener;
- publicclassScrollTabActivityextendsActivity{
- privateScrcoolTabscrcoolTab;
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- scrcoolTab=(ScrcoolTab)findViewById(R.id.scrcoolTab);
- scrcoolTab.setAdapter(newScrcoolTabAdapter(R.layout.tab_item,newString[]{"进入首页","用户调研","下载中心","联系我们"}));
- scrcoolTab.setOnItemClickListener(newOnItemClickListener(){
- @Override
- publicvoidonItemClickListener(Viewv,intposition){
- //Toast.makeText(ScrollTabActivity.this,"点击了"+position,Toast.LENGTH_SHORT).show();
- }
- });
- //scrcoolTab.setDefaultTab(1);
- }
- publicvoiditemOnclick(Viewv){
- ViewParentparent=v.getParent().getParent();
- if(parentinstanceofScrcoolTab){
- ScrcoolTabtab=(ScrcoolTab)parent;
- tab.postInvalidate();
- }
- System.out.println(parent);
- }
- @Override
- publicvoidfinish(){
- super.finish();
- Process.killProcess(Process.myPid());
- }
- }
- ScrollTab.rar(63.1 KB)
- 下载次数: 632
更多相关文章
- Android:LayoutInflater的使用
- Android控件之ListView
- android 自动化测试之MonkeyRunner学习(二)
- 【Java&Android开源库代码剖析】のAndroid-Universal-Image-Load
- Android的GridView简单使用实例(附Demo)
- android2.3修改ethernet默认为不选中状态
- 【Android(安卓)Native Code开发系列】六 一个Native Service的
- Android中EditText控件的几种使用方法
- android开发实例06:popwindow实现下拉菜单