ListView里的焦点移动原始的效果是一种立即变化的效果,我们可以进行让焦点有一种滑动的效果。
在XML里定义ListView的时候,参考如下来定义:
<RelativeLayout android:id="@+id/ui4_main_left_layout" android:layout_width="367dp" android:layout_height="586dp" android:layout_marginBottom="60dp" android:layout_marginStart="135dp" android:layout_marginTop="60dp" android:background="@drawable/mainmenuleftlistbg" android:orientation="vertical"> <com.amlogic.dvb_ui4.Item_selected_view android:id="@+id/tv_menu_left_selected_view" android:layout_width="1dp" android:layout_height="1dp" /> <ListView android:id="@+id/ui4_main_leftlistview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="110dp" android:divider="@null" android:listSelector="@drawable/ui4mainmenurightlist_selector"> </ListView>
ListView中的listSelector属性对应的文件在drawable目录下,内容为:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"> <shape> <solid android:color="@android:color/transparent" /> </shape> </item> <item android:state_focused="true"> <shape> <solid android:color="@android:color/transparent" /> </shape> </item> </selector>
Item_selected_view是一个自定义View,就是我们的划条,定义如下:
package com.amlogic.dvb_ui4; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.app.ActionBar.LayoutParams; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; public class Item_selected_view extends View { private static final String TAG = Item_selected_view.class.getSimpleName(); private int smooth_duration; private int top_margin; private int left_margin; private boolean isInited; public Item_selected_view(Context context, AttributeSet attrs) { super(context, attrs); } public void SmoothTo_By_XY(int x, int y, int duration) { float TranslationX = x; float TranslationY = y; ObjectAnimator transAnim1 = ObjectAnimator.ofFloat(this, "x", TranslationX); ObjectAnimator transAnim2 = ObjectAnimator.ofFloat(this, "y", TranslationY); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(transAnim1, transAnim2); animSetXY.setDuration(duration); animSetXY.start(); } public void XY_SmoothTo(View target, int duration, final BaseAdapter adapter, final boolean update_adapter) { if(null == target) { return ; } float TranslationX = target.getX() + left_margin; float TranslationY = target.getY() + top_margin; ObjectAnimator transAnim1 = ObjectAnimator.ofFloat(this, "x", TranslationX); ObjectAnimator transAnim2 = ObjectAnimator.ofFloat(this, "y", TranslationY); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(transAnim1, transAnim2); animSetXY.setDuration(duration); animSetXY.start(); } public void Y_SmoothTo(View target, int duration, final BaseAdapter adapter, final boolean update_adapter) { if(null == target) { return ; } float TranslationY = target.getY() + top_margin; ObjectAnimator transAnim = ObjectAnimator.ofFloat(this, "y", TranslationY); transAnim.setDuration(duration); transAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if(update_adapter && (adapter != null)) { adapter.notifyDataSetChanged(); } } }); transAnim.start(); } public void set_topMargin(int topMargin) { this.top_margin = topMargin; } public void set_leftMargin(int leftMargin) { this.left_margin = leftMargin; } public void smoothTo(View target, int duration) { if(null == target) { return ; } if(!isInited){ init(target); } float TranslationY = target.getY() + top_margin; float TranslationX = target.getX() + (int)((View)target.getParent()).getX()+ left_margin; Log.i(TAG, "item_selected_view smoothTo TranslationX = "+TranslationX + " this x = "+this.getX()); if((float)this.getX() != TranslationX){ init(target); } // ObjectAnimator transAnim = ObjectAnimator.ofFloat(this, "y", TranslationY); // transAnim.setDuration(duration); // transAnim.start(); ObjectAnimator transAnimx = ObjectAnimator.ofFloat(this, "x", TranslationX); ObjectAnimator transAnimy = ObjectAnimator.ofFloat(this, "y", TranslationY); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(transAnimx, transAnimy); animSetXY.setDuration(duration); animSetXY.start(); } public void forceSmoothTo(int tox,int toy,int width,int height,int duration){ ViewGroup.LayoutParams lp; lp = this.getLayoutParams(); lp.width = width; lp.height = height; this.setLayoutParams(lp); float TranslationY = toy; float TranslationX = tox; ObjectAnimator transAnimx = ObjectAnimator.ofFloat(this, "x", TranslationX); ObjectAnimator transAnimy = ObjectAnimator.ofFloat(this, "y", TranslationY); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(transAnimx, transAnimy); animSetXY.setDuration(duration); animSetXY.start(); } public void init_xy_position(View view) { if(view == null){ return ; } int x = (int)view.getX() + left_margin; int y = (int)view.getY() + top_margin; this.setX(x); this.setY(y); } public void set_x_position(int x) { this.setX(x); } public void set_y_position(int y) { this.setY(y); } public void set_height_width(int height, int width) { ViewGroup.LayoutParams lp; lp = this.getLayoutParams(); lp.width = width; lp.height = height; this.setLayoutParams(lp); } public void setMargin(int left_margin, int top_margin){ this.left_margin = left_margin; this.top_margin = top_margin; } public void set_smooth_duration(int duration) { smooth_duration = duration; } public void set_width_height(View view) { if(view == null){ return; } ViewGroup.LayoutParams lp; int width; int height; lp = this.getLayoutParams(); width = view.getWidth(); height = view.getHeight(); lp.width = width; lp.height = height; this.setLayoutParams(lp); } public void set_width_height(int width, int height) { ViewGroup.LayoutParams lp = this.getLayoutParams(); lp.width = width; lp.height = height; this.setLayoutParams(lp); } public void init(View view) { if(view == null){ Log.i(TAG, "item_selected_view init View = null"); isInited = false; return ; } isInited = true; ViewGroup.LayoutParams lp; int width; int height; int x = (int)view.getX() + (int)((View)view.getParent()).getX() + left_margin; int y = (int)view.getY() + top_margin; Log.i(TAG, "item_selected_view init x = "+x+" y = "+y); this.setX(x); this.setY(y); lp = this.getLayoutParams(); width = view.getWidth(); height = view.getHeight(); Log.i(TAG, "item_selected_view init width = "+width+" height = "+height); lp.width = width; lp.height = height; this.setLayoutParams(lp); } }
确定滑条的初始位置可以在ListView控件的onFocusChange中做到。
ui4_main_leftlistview.setOnFocusChangeListener(new View.OnFocusChangeListener(){ @Override public void onFocusChange(View view, boolean isFocus) { if (isFocus) { //Log.e("wujiang", "ui4_main_leftlistview get fouces"); ui4_main_leftlistview.postDelayed(new Runnable() { @Override public void run() { //下面是确定left_selected_view的初始位置 int topMargin = ((RelativeLayout.LayoutParams) ui4_main_leftlistview.getLayoutParams()).topMargin; left_selected_view.set_leftMargin(0); left_selected_view.set_topMargin(topMargin); left_selected_view.init_xy_position(ui4_main_leftlistview.getSelectedView()); left_selected_view.set_width_height(ui4_main_leftlistview.getSelectedView()); left_selected_view.setBackgroundResource(R.drawable.ui4mainleftlist_focused); } }, 200); ui4_main_rightlistview.setSelection(0); } else { left_selected_view.setBackgroundResource(R.drawable.ui4mainleftlist_unfocused); } } });
当我们上下移动时,滑条的位置当然是在ListView控件的onItemSelected中来做。
@Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { left_selected_view.Y_SmoothTo(view, 100, mainLeftListAdapter, false);
这样就实现了ListView控件焦点滑动的效果。
这里需要注意的就是,ListView空间在定义的时候可能会设置layout_marginTop,在确定滑条的初始位置时,滑条的Y坐标一定要加上这个Top。