这里实现的功能是从主页布局的fragment点击跳转到一个acitivity,然后顶部是一个切换的segment顶部是一个listview,点击segment分段让listview加载不同的内容。我这里没再使用viewpager,应该使用viewpager+listview也能实现。我这里使用的算是一个自定义的viewpager。下面我主要围绕TranslateAnimation segment切换动画类来谈,这东西吭比较多,我原本也是才做android开发的, 它这个类实现动画很多效果上的bug,效果bug直接说明android这个动画类没ios做的好,我遇到的这些效果bug主要出现在控件移动的距离和移动时间上的计算上。比如移动动画带有缓冲,或则移动分段两个以上,就没有动画效果。
下面先帖上布局,主要就是
class="code_img_closed" src="/Upload/Images/2017090821/0015B68B3C38AA5B.gif" alt=""><?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:background="@color/white_color" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="@dimen/navigationbar_height" android:textSize="@dimen/title_fontsize" android:text="在线视频" android:textColor="@color/navigation_title_color" android:background="@color/navigationbar_backround_color" android:gravity="center"/> <LinearLayout android:layout_width="match_parent" android:layout_height="53dp" android:orientation="vertical" android:animateLayoutChanges="true" > <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" > <TextView android:layout_width="match_parent" android:layout_height="@dimen/navigationbar_height" android:layout_weight="1" android:textSize="@dimen/title_fontsize" android:text="推荐" android:id="@+id/tuijianVideo" android:textColor="@color/hot_price_color" android:background="@color/navigationbar_backround_color" android:gravity="center"/> <TextView android:layout_width="match_parent" android:layout_height="@dimen/navigationbar_height" android:textSize="@dimen/title_fontsize" android:layout_weight="1" android:text="电影" android:id="@+id/dianying" android:textColor="@color/navigation_title_color" android:background="@color/navigationbar_backround_color" android:gravity="center"/> <TextView android:layout_width="match_parent" android:layout_height="@dimen/navigationbar_height" android:textSize="@dimen/title_fontsize" android:text="电视" android:id="@+id/dianshi" android:layout_weight="1" android:textColor="@color/navigation_title_color" android:background="@color/navigationbar_backround_color" android:gravity="center"/> <TextView android:layout_width="match_parent" android:layout_height="@dimen/navigationbar_height" android:textSize="@dimen/title_fontsize" android:text="动漫" android:layout_weight="1" android:id="@+id/dongman" android:textColor="@color/navigation_title_color" android:background="@color/navigationbar_backround_color" android:gravity="center"/> <TextView android:layout_width="match_parent" android:layout_height="@dimen/navigationbar_height" android:textSize="@dimen/title_fontsize" android:text="综艺" android:id="@+id/zongyi" android:layout_weight="1" android:textColor="@color/navigation_title_color" android:background="@color/navigationbar_backround_color" android:gravity="center"/> </LinearLayout> <ImageView android:layout_width="match_parent" android:id="@+id/Imagezhishiqi" android:layout_height="3dp" android:background="@color/hot_price_color"/> </LinearLayout> <com.lt.WBTaoBaoKe.custom.xPullRefresh.XListView android:id="@+id/xListView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:cacheColorHint="#00000000"> </com.lt.WBTaoBaoKe.custom.xPullRefresh.XListView> </LinearLayout>logs_code_collapse">View Code
下面贴代码,有动画说明的详细注视
public class HomeFragment_VideoActivity extends Activity implements View.OnClickListener { private ListViewAdapter listViewAdapter; private ViewPagerAdapter viewPagerAdapter; private Context context; private LinearLayout.LayoutParams zhishiqilinearParams; private int zhishiqiWidth; private ImageView zhishiqi; private TextView tuijianView; private TextView dianying; private TextView dianshi; private TextView dongman; private TextView zongyi; private int currentTopItemIndex; private TranslateAnimation moveAnimation; private int moveStepValue; //视频数据 private XListView listView; private JSONArray CurrentVideoDataArray; private int currentVideoPageIndex; private String refreshTime = "第一次刷新"; private ViewGroup.MarginLayoutParams margin; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = getApplicationContext(); setContentView(R.layout.home_video_activity); //指示器 zhishiqi = (ImageView) findViewById(R.id.Imagezhishiqi); currentTopItemIndex = 1; DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int width = dm.widthPixels; //由于我们分段是固定的5段,所以这里先使用手机屏幕宽度/5,计算出分段指示器的宽度 zhishiqiWidth = width / 5; //由于在固定布局中无法准确设置出指示器的宽度,所以这里需要使用计算出的宽度重新设置指示器宽度 zhishiqilinearParams = (LinearLayout.LayoutParams) zhishiqi.getLayoutParams(); zhishiqilinearParams.width = zhishiqiWidth; zhishiqi.setLayoutParams(zhishiqilinearParams); //下面都是每个分段里面显示文字的textview控件 tuijianView = (TextView) findViewById(R.id.tuijianVideo); dianying = (TextView) findViewById(R.id.dianying); dianshi = (TextView) findViewById(R.id.dianshi); dongman = (TextView) findViewById(R.id.dongman); zongyi = (TextView) findViewById(R.id.zongyi); tuijianView.setTag(1); dianying.setTag(2); dianshi.setTag(3); dongman.setTag(4); zongyi.setTag(5); tuijianView.setOnClickListener(this); dianying.setOnClickListener(this); dianshi.setOnClickListener(this); dongman.setOnClickListener(this); zongyi.setOnClickListener(this); } //每个分段textview点击事件 @Override public void onClick(View v) { int tag = (Integer) v.getTag(); //获得控件移动的段数确定移动方向,如果是正数表示向右移动,负数左移动 moveStepValue = tag - currentTopItemIndex; switch (tag) { case 1: if (currentTopItemIndex == 1) { return; } else { currentTopItemIndex = tag; tuijianView.setTextColor(this.getResources().getColor(R.color.hot_price_color)); dianying.setTextColor(this.getResources().getColor(R.color.white_color)); dianshi.setTextColor(this.getResources().getColor(R.color.white_color)); dongman.setTextColor(this.getResources().getColor(R.color.white_color)); zongyi.setTextColor(this.getResources().getColor(R.color.white_color)); } break; case 2: if (currentTopItemIndex == 2) { return; } else { currentTopItemIndex = tag; tuijianView.setTextColor(this.getResources().getColor(R.color.white_color)); dianying.setTextColor(this.getResources().getColor(R.color.hot_price_color)); dianshi.setTextColor(this.getResources().getColor(R.color.white_color)); dongman.setTextColor(this.getResources().getColor(R.color.white_color)); zongyi.setTextColor(this.getResources().getColor(R.color.white_color)); } break; case 3: if (currentTopItemIndex == 3) { return; } else { currentTopItemIndex = tag; tuijianView.setTextColor(this.getResources().getColor(R.color.white_color)); dianying.setTextColor(this.getResources().getColor(R.color.white_color)); dianshi.setTextColor(this.getResources().getColor(R.color.hot_price_color)); dongman.setTextColor(this.getResources().getColor(R.color.white_color)); zongyi.setTextColor(this.getResources().getColor(R.color.white_color)); } break; case 4: if (currentTopItemIndex == 4) { return; } else { currentTopItemIndex = tag; tuijianView.setTextColor(this.getResources().getColor(R.color.white_color)); dianying.setTextColor(this.getResources().getColor(R.color.white_color)); dianshi.setTextColor(this.getResources().getColor(R.color.white_color)); dongman.setTextColor(this.getResources().getColor(R.color.hot_price_color)); zongyi.setTextColor(this.getResources().getColor(R.color.white_color)); } break; default: if (currentTopItemIndex == 5) { return; } else { currentTopItemIndex = tag; tuijianView.setTextColor(this.getResources().getColor(R.color.white_color)); dianying.setTextColor(this.getResources().getColor(R.color.white_color)); dianshi.setTextColor(this.getResources().getColor(R.color.white_color)); dongman.setTextColor(this.getResources().getColor(R.color.white_color)); zongyi.setTextColor(this.getResources().getColor(R.color.hot_price_color)); } break; } margin = new ViewGroup.MarginLayoutParams(tuijianView.getLayoutParams()); //Animation.RELATIVE_TO_SELF, 0.0f,这两个其实是一个参数(合并一起看,表示相对定位+坐标变动值),所以只看2/4/6/8这4个参数 //第一个值:0.0f表示控件的原始x坐标不变动。 //第二个值moveStepValue*0.5f表示原始x坐标前提下变动的值 //第三个值0.0f表示y坐标变动 //第四个值0.0f表示原始y坐标前提下变动的值 //重点:这里由于我们只是x坐标左右移动,所以y轴的值一只不变动0.0f 0.0f //当moveStepValue为负数时,moveStepValue*0.5f segment是往左移动,正数往右移动,这样动画效果才不会有bug, moveAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, moveStepValue * 0.5f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f); //下面的代码是计算动画的执行时间,如果不计算就会出现切换分段数量不一致,指示器的动画执行速度太快或太慢。 if (moveStepValue < 1) { moveStepValue = moveStepValue * -1; } moveAnimation.setDuration(moveStepValue * 70); moveAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { zhishiqi.clearAnimation(); //移动效果实现之后,还需要将移动segment分段的margin设置一次,如果不设置动画又会反回去,为什么这样我觉得应该是和android是使用xhtml布局的原因。 zhishiqilinearParams.setMargins((currentTopItemIndex - 1) * zhishiqiWidth, margin.topMargin, zhishiqiWidth, zhishiqilinearParams.height); zhishiqi.setLayoutParams(zhishiqilinearParams); } }); zhishiqi.startAnimation(moveAnimation); zhishiqi.setVisibility(View.VISIBLE); } }