重写已被弃用的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
- 重写已被弃用的Gallery
- 在重写Gallery之后 解决重写Adapter内加载Layout过小的问题
- 重写Gallery 防止滚动过头
- Android 重写Gallery 左对齐
- 重写Gallery控件,控制滑动速度
- 【Android】Gallery重写OnItemSelectedListener时滑动不流畅的解决办法——获取停止时的位置
- 点击Gallery弹出对应的Gallery大图
- Gallery的小技巧
- android Gallery的学习心得
- Gallery 的一些使用方法
- Gallery的使用
- 向左对齐的Gallery
- android--Gallery的实现
- 立体感的Gallery
- android gallery的使用
- 向左对齐的Gallery
- Gallery控件的使用
- Gallery的简单应用
- Hadoop学习笔记—20.网站日志分析项目案例(二)数据清洗
- TCP和UDP的区别和优缺点
- 使用gitolite管理git权限
- Lua查找表元素过程(元表、__index方法是如何工作的)
- Spring事物设置回滚点
- 重写已被弃用的Gallery
- Unity3D 快捷键
- MySQL技巧#常用MySQL数据库命令总结
- Java环境配置
- 蓝桥杯算法训练——2的次幂表示 (递归)
- html网页css的三种引入方式
- 数据结构--最小生成树详解
- linux定时备份MySQL数据库并删除七天前的备份文件
- 查看mysql数据库及表编码格式