重写已被弃用的Gallery

来源:互联网 发布:长春典恒网络发展有 编辑:程序博客网 时间:2024/05/17 23:02

公司以前的Camera项目使用了Gallery,该控件存在问题,有些偶现Bug无法解决。比如 狂点+滑动 会偶现错乱。Gallery原生方法未加锁同步,又不可重写,导致该Bug不可控。

当用户点击又滑动的时候,下面这两个方法就一起调用,偶现Position错乱

    mGalleryView.setOnItemClickListener(new OnItemClickListener());    mGalleryView.setSelection(mCurrentIndex);

既然这样,那就从新实现有Gallery效果的控件
效果:可以点击切换,也可以外部布局切换。
这里写图片描述

首先实现下图中的自定义textView实现选中缩放效果。

public class AnimaTextView extends TextView{    private AnimatorSet scaleTextAnimator;        public AnimaTextView(Context context, AttributeSet attrs, int defStyle)    {        super(context, attrs, defStyle);        init();    }    public AnimaTextView(Context context, AttributeSet attrs)    {        this(context, attrs,0);      }    public AnimaTextView(Context context)    {        this(context,null);         }    private void init()    {        if (this.scaleTextAnimator == null)        {          this.scaleTextAnimator = new AnimatorSet();          ObjectAnimator localObjectAnimator1 = ObjectAnimator.ofFloat(this, "ScaleX", new float[] { 1.0F, 1.05F });          localObjectAnimator1.setDuration(500);          ObjectAnimator localObjectAnimator2 = ObjectAnimator.ofFloat(this, "ScaleY", new float[] { 1.0F, 1.05F });          localObjectAnimator2.setDuration(500);          this.scaleTextAnimator.play(localObjectAnimator2).with(localObjectAnimator1);        }    }    @Override    public void setSelected(boolean selected)    {        super.setSelected(selected);        if(selected)        {            scaleTextAnimator.start();        }else        {            setScaleX(1.0F);            setScaleY(1.0F);        }    }}

然后写放置AnimaTextView 的ViewGroup。

public class JScrollParentView extends LinearLayout implements OnClickListener{    private AnimaTextView[] mItemView = null;    private CharSequence[] itemsEntry = null;    private int mItemSpace = 36;    private Context mContext = null;    private int mItemsCount = -1;    private ColorStateList textColor;    private float textSize = 14;    private OnItemSelected mOnItemSelcted = null;    private TextView mCurrentView = null;    private int mCurrentPosition = 0;    public interface OnItemSelected    {        void onItemSelected(int position);    }    public JScrollParentView(Context context)    {        this(context,null);          }    public JScrollParentView(Context context, AttributeSet attrs)    {        this(context, attrs,0);    }    public JScrollParentView(Context context, AttributeSet attrs, int defStyle)    {        super(context, attrs, defStyle);        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.JScrollParentView);        itemsEntry = ta.getTextArray(R.styleable.JScrollParentView_item_texts);        mItemSpace = ta.getDimensionPixelSize(R.styleable.JScrollParentView_item_space, 36);        textColor = ta.getColorStateList(R.styleable.JScrollParentView_item_texts_colors);        textSize = ta.getFloat(R.styleable.JScrollParentView_item_texts_size, 12f);        mItemsCount = itemsEntry.length;        ta.recycle();        setOrientation(HORIZONTAL);        setGravity(Gravity.LEFT);        setPadding(0, 0, 0, 0);        mContext = context;              initView();    }    private void initView()    {        if (mItemsCount > 0)        {            mItemView = new AnimaTextView[mItemsCount];            for (int i = 0; i < mItemsCount; i++)            {                LayoutParams itemParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);                AnimaTextView item = new AnimaTextView(mContext);                item.setTextColor(textColor);                item.setTextSize(textSize);                item.setText(itemsEntry[i].toString());                item.setGravity(Gravity.CENTER);                item.setId(i);                item.setShadowLayer(1, 0, 0, 0x50000000);                item.setOnClickListener(this);               // if(i != 0)                {                    itemParams.leftMargin = mItemSpace;                }                addView(item,itemParams);                mItemView[i] = item;            }        }    }    @Override    public void onClick(View v)    {        if(mOnItemSelcted != null)        {            if(mCurrentView != null && mCurrentPosition != v.getId())            {                mOnItemSelcted.onItemSelected(v.getId());            }        }    }    public int getLeftPointX(int position)    {        if(position > mItemsCount -1 || mItemsCount <1)        {            return 0;        }        int paddingLeft = 0;        for(int i = position; i >= 0; i--)        {            int itemWidth = getChildAt(i).getMeasuredWidth();             if( i == position)            {                paddingLeft = paddingLeft + itemWidth/2 + mItemSpace; //最后一个是itemWidth/2 + mItemSpace,以后都是itemWidth + mItemSpace            }else            {                paddingLeft = paddingLeft + itemWidth + mItemSpace;             }        }        return paddingLeft;    }    public void setOnItemSelectedListener(OnItemSelected listener)    {        mOnItemSelcted = listener;    }    public void updateSelcted(int position)    {        if(mCurrentView != null)        {            mCurrentView.setSelected(false);        }        mCurrentView = mItemView[position];        mCurrentPosition = position;        mCurrentView.setSelected(true);    }       }
public class JScrollPanelLayout extends FrameLayout implements OnItemSelected ,OnGestureListener{    private int mLeftStart = 0;    private JScrollParentView mItemLayout = null;    private int mCurrentPosition =2;    private int mItemCount = -1;    private int mWidth = 0;    private int mDisplayWith;    private Context mContext = null;    private GestureDetector mDetector = null;    private static final int SLIDE_MIN_PIXCEL = 25;        public JScrollPanelLayout(Context context)    {        this(context,null);        // TODO Auto-generated constructor stub    }    public JScrollPanelLayout(Context context, AttributeSet attrs, int defStyle)    {        super(context, attrs, defStyle);        mContext = context;        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);        mDisplayWith = wm.getDefaultDisplay().getWidth();        mDetector =  new GestureDetector(context,this);    }    public JScrollPanelLayout(Context context, AttributeSet attrs)    {        this(context, attrs,0);        // TODO Auto-generated constructor stub    }    @Override    protected void onFinishInflate()    {        // TODO Auto-generated method stub        super.onFinishInflate();        mItemLayout = (JScrollParentView)findViewById(R.id.scroll_item);        mItemLayout.setOnItemSelectedListener(this);        mWidth = getWidth();        mItemCount = mItemLayout.getChildCount();        //caculateLeftStart();    }    //每次通过动态改变mLeftStart,进行滑动    @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom)    {        // TODO Auto-generated method stub        super.onLayout(changed, left, top, right, bottom);        if(mItemLayout != null)        {            mItemLayout.layout(mLeftStart,mItemLayout.getTop(), mLeftStart + mItemLayout.getWidth(), mItemLayout.getBottom());        }    }  //计算mLeftStart ,  mItemLayout.updateSelcted(mCurrentPosition)修改选中View    public void caculateLeftStart()    {        if(mWidth == 0)        {            mWidth = mDisplayWith;        }        int nextLeftStart = 0;        if(mItemLayout != null)        {            nextLeftStart = mWidth/2 - mItemLayout.getLeftPointX(mCurrentPosition);//确定中心位置        }        ValueAnimator anim = ValueAnimator.ofInt(mLeftStart, nextLeftStart);        anim.setDuration(300);        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()        {            @Override            public void onAnimationUpdate(ValueAnimator animation)            {                mLeftStart = (Integer) animation.getAnimatedValue();                requestLayout();                mItemLayout.updateSelcted(mCurrentPosition);            }        });        anim.start();    }    @Override    public void onItemSelected(int position)    {        if(mCurrentPosition != position)        {            mCurrentPosition = position;            caculateLeftStart();        }    }    @Override    public boolean onDown(MotionEvent e)    {        // TODO Auto-generated method stub        return true;    }    @Override    public void onShowPress(MotionEvent e)    {        // TODO Auto-generated method stub    }    @Override    public boolean onSingleTapUp(MotionEvent e)    {        // TODO Auto-generated method stub        return false;    }    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)    {        // TODO Auto-generated method stub        return false;    }    @Override    public void onLongPress(MotionEvent e)    {        // TODO Auto-generated method stub    }    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)    {        doFling(e1,e2,velocityX,velocityY);        return false;    }    @Override    public boolean onTouchEvent(MotionEvent event)    {        // TODO Auto-generated method stub        return mDetector.onTouchEvent(event);    }    //e1:手势起点的移动事件    //e2: 当前手势点的移动事件    //velocityX:每秒x轴方向移动的像素    //velocityY: 每秒y轴方向移动的像素    public void doFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)    {        if(Math.abs(e1.getX() - e2.getX()) > Math.abs(e1.getY() - e2.getY())){            if (e1.getX() - e2.getX() > SLIDE_MIN_PIXCEL) {                if(mCurrentPosition != mItemCount -1)                {                    onItemSelected(mCurrentPosition +1);                }            } else if (e1.getX() - e2.getX() < -SLIDE_MIN_PIXCEL) {                if(mCurrentPosition != 0)                {                    onItemSelected(mCurrentPosition - 1);                }            }        }    }}

使用:

public class CenterIndicatorActivity extends Activity implements OnGestureListener{    private JScrollPanelLayout mJScrollPanelLayout;    private GestureDetector mDetector = null;    @Override    protected void onCreate(Bundle savedInstanceState)    {        // TODO Auto-generated method stub        super.onCreate(savedInstanceState);        setContentView(R.layout.center_indicator_activity);        mJScrollPanelLayout = (JScrollPanelLayout)findViewById(R.id.scroll_parent);        mJScrollPanelLayout.postDelayed(new Runnable(){            @Override            public void run()            {                mJScrollPanelLayout.caculateLeftStart();                mJScrollPanelLayout.setVisibility(View.VISIBLE);            }}, 300);        mDetector = new GestureDetector(this, this);    }    @Override    public boolean onDown(MotionEvent e)    {        // TODO Auto-generated method stub        return true;    }    @Override    public void onShowPress(MotionEvent e)    {        // TODO Auto-generated method stub    }    @Override    public boolean onSingleTapUp(MotionEvent e)    {        // TODO Auto-generated method stub        return false;    }    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)    {        // TODO Auto-generated method stub        return false;    }    @Override    public void onLongPress(MotionEvent e)    {        // TODO Auto-generated method stub    }    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)    {        mJScrollPanelLayout.doFling(e1, e2, velocityX, velocityY);        return false;    }    @Override    public boolean onTouchEvent(MotionEvent event)    {        // TODO Auto-generated method stub        return mDetector.onTouchEvent(event);    }}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:jpower="http://schemas.android.com/apk/res/com.jimmy.jpower"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <com.jimmy.jpower.widget.centerIndicator.JScrollPanelLayout        android:id="@+id/scroll_parent"         android:layout_width="match_parent"        android:layout_height="48dip"        android:visibility="invisible"        android:layout_centerInParent="true"         android:background="@color/tab_bg">        <com.ws.jpower.widget.centerIndicator.JScrollParentView           android:id="@+id/scroll_item"            android:layout_width="match_parent"           android:layout_height="48dip"           jpower:item_space="18dp"           jpower:item_texts="@array/jpower_center_list"           jpower:item_texts_size="14"           jpower:item_texts_colors="@color/text_color">        </com.ws.jpower.widget.centerIndicator.JScrollParentView>    </com.ws.jpower.widget.centerIndicator.JScrollPanelLayout></RelativeLayout>
 <array name="jpower_center_list">        <item>Video</item>        <item>Photo</item>        <item>Beauty</item>        <item>Pano</item>    </array>
1 0
原创粉丝点击