自定义view:图片显示指示器
2015-03-06 11:00
239 查看
本篇文章使用Gallally控件和自定义view,实现一个带有图片指示器的图片集的展示效果。
1.实现的效果
显示一组可以滑动的图片,随着图片的切换,指示器小圆点也随着切换。
2.自定义view的步骤
(1)、自定义View的属性
(2)、在View的构造方法中获得我们自定义的属性
(3)、重写onMesure
(4)、重写onDraw
(3)不一定是必须的,当然了大部分情况下还是需要重写的。
1、自定义View的属性,首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。
我们定义了5个属性,format是值该属性的取值类型:
一共有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;
在图片展示的布局中,我们声明Gallery控件以及自定义属性。布局文件head_view.xml内容如下:
记住,一定要引入 xmlns:app="http://schemas.android.com/apk/res/com.dream.myqiyi" 命名空间,后面的包路径指的是项目的package。
2, 自定义FlowIndicator类继承View类,在自定义的FlowIndicator类构造方法中,获得我们的自定义样式属性,并重写View类的onMeasure()和onView()方法。
在onMeasure函数中,系统帮我们测量的高度和宽度都是MATCH_PARNET,当我们设置明确的宽度和高度时,系统帮我们测量的结果就是我们设置的结果,当我们设置为WRAP_CONTENT,或者MATCH_PARENT系统帮我们测量的结果就是MATCH_PARENT的长度。所以,当设置了WRAP_CONTENT时,我们需要自己进行测量,即重写onMesure方法”:重写之前先了解MeasureSpec的specMode,一共三种类型:
EXACTLY:一般是设置了明确的值或者是MATCH_PARENT
AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT
UNSPECIFIED:表示子布局想要多大就多大,很少使用。
需要重写onMeasure方法,计算自定义view的大小。
3,Gallery数据适配器类
4,主Activity
实现图片定时自动切换和手动滑动切换。
1.实现的效果
显示一组可以滑动的图片,随着图片的切换,指示器小圆点也随着切换。
2.自定义view的步骤
(1)、自定义View的属性
(2)、在View的构造方法中获得我们自定义的属性
(3)、重写onMesure
(4)、重写onDraw
(3)不一定是必须的,当然了大部分情况下还是需要重写的。
1、自定义View的属性,首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="FlowIndicator"> <attr name="count" format="integer" /> <attr name="space" format="dimension" /> <attr name="point_size" format="dimension" /> <attr name="point_seleted_color" format="color|reference" /> <attr name="point_normal_color" format="color|reference" /> <attr name="point_radius" format="dimension" /> </declare-styleable> </resources>
我们定义了5个属性,format是值该属性的取值类型:
一共有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;
在图片展示的布局中,我们声明Gallery控件以及自定义属性。布局文件head_view.xml内容如下:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.dream.myqiyi" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Gallery android:id="@+id/home_gallery" android:layout_width="fill_parent" android:layout_height="wrap_content" android:spacing="5dip" /> <LinearLayout android:id="@+id/linearLayout1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="#65000000" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginBottom="5dip" android:layout_marginTop="5dip" android:text="承影之奇艺UIdemo" android:textColor="#ffffff" android:textSize="18dip" /> <com.dream.myqiyi.widget.FlowIndicator android:id="@+id/myView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dip" app:count="4" android:gravity="center" app:point_normal_color="#45000000" app:point_radius="3dip" app:point_seleted_color="#ffffff" app:point_size="5dip" app:space="10dip" /> </LinearLayout> </FrameLayout>
记住,一定要引入 xmlns:app="http://schemas.android.com/apk/res/com.dream.myqiyi" 命名空间,后面的包路径指的是项目的package。
2, 自定义FlowIndicator类继承View类,在自定义的FlowIndicator类构造方法中,获得我们的自定义样式属性,并重写View类的onMeasure()和onView()方法。
public class FlowIndicator extends View { private int count; private float space, radius; private int point_normal_color, point_seleted_color; // 选中 private int seleted = 0; // background seleted normal public FlowIndicator(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FlowIndicator); count = a.getInteger(R.styleable.FlowIndicator_count, 4); space = a.getDimension(R.styleable.FlowIndicator_space, 9); radius = a.getDimension(R.styleable.FlowIndicator_point_radius, 9); point_normal_color = a.getColor( R.styleable.FlowIndicator_point_normal_color, 0x000000); point_seleted_color = a.getColor( R.styleable.FlowIndicator_point_seleted_color, 0xffff07); int sum = attrs.getAttributeCount(); if (Constans.DEBUG) { String str = ""; for (int i = 0; i < sum; i++) { String name = attrs.getAttributeName(i); String value = attrs.getAttributeValue(i); str += "attr_name :" + name + ": " + value + "\n"; } Log.i("attribute", str); } a.recycle(); } public void setSeletion(int index) { this.seleted = index; invalidate(); } public void setCount(int count) { this.count = count; invalidate(); } public void next() { if (seleted < count - 1) seleted++; else seleted = 0; invalidate(); } public void previous() { if (seleted > 0) seleted--; else seleted = count - 1; invalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setAntiAlias(true); float width = (getWidth() - ((radius * 2 * count) + (space * (count - 1)))) / 2.f; for (int i = 0; i < count; i++) { if (i == seleted) paint.setColor(point_seleted_color); else paint.setColor(point_normal_color); canvas.drawCircle(width + getPaddingLeft() + radius + i * (space + radius + radius), getHeight() / 2, radius, paint); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } private int measureWidth(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { result = (int) (getPaddingLeft() + getPaddingRight() + (count * 2 * radius) + (count - 1) * radius + 1); if (specMode == MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } } return result; } private int measureHeight(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { result = (int) (2 * radius + getPaddingTop() + getPaddingBottom() + 1); if (specMode == MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } } return result; } }
在onMeasure函数中,系统帮我们测量的高度和宽度都是MATCH_PARNET,当我们设置明确的宽度和高度时,系统帮我们测量的结果就是我们设置的结果,当我们设置为WRAP_CONTENT,或者MATCH_PARENT系统帮我们测量的结果就是MATCH_PARENT的长度。所以,当设置了WRAP_CONTENT时,我们需要自己进行测量,即重写onMesure方法”:重写之前先了解MeasureSpec的specMode,一共三种类型:
EXACTLY:一般是设置了明确的值或者是MATCH_PARENT
AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT
UNSPECIFIED:表示子布局想要多大就多大,很少使用。
需要重写onMeasure方法,计算自定义view的大小。
3,Gallery数据适配器类
public class GalleryAdapter extends BaseAdapter { Context mContext; int[] res = new int[] { R.drawable.t1, R.drawable.t2, R.drawable.t3, R.drawable.t1, R.drawable.t2, R.drawable.t3, R.drawable.t1, R.drawable.t2, R.drawable.t3 }; public GalleryAdapter(Context cnt) { 4000 this.mContext = cnt; } @Override public int getCount() { // TODO Auto-generated method stub return res.length; } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return 0; } @Override public View getView(int arg0, View arg1, ViewGroup arg2) { // TODO Auto-generated method stub if (arg1 == null) { arg1 = LayoutInflater.from(mContext).inflate(R.layout.gallery_item, null); } ImageView img = (ImageView) arg1.findViewById(R.id.home_img); img.setImageResource(res[arg0]); return arg1; } }
4,主Activity
public class HomeActivity extends Activity { static final int SCROLL_ACTION = 0; int[] tags = new int[] { 0, 0, 0, 0, 0 }; Gallery mGallery; GalleryAdapter mGalleryAdapter; FlowIndicator mMyView; Timer mTimer; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.home_activity); prepareView(); mTimer = new Timer(); mTimer.scheduleAtFixedRate(new MyTask(), 0, 4000); } private void prepareView() { mExpandableListView = (ExpandableListView) findViewById(R.id.expandableListView1); MyListAdapter adapter = new MyListAdapter(); View header = LayoutInflater.from(this).inflate(R.layout.header_view, null); mGallery = (Gallery) header.findViewById(R.id.home_gallery); mMyView = (FlowIndicator) header.findViewById(R.id.myView); mGalleryAdapter = new GalleryAdapter(this); mMyView.setCount(mGalleryAdapter.getCount()); mGallery.setAdapter(mGalleryAdapter); mGallery.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub mMyView.setSeletion(arg2); } @Override public void onNothingSelected(AdapterView<?> arg0) { // TODO Auto-generated method stub } }); } private class MyTask extends TimerTask { @Override public void run() { mHandler.sendEmptyMessage(SCROLL_ACTION); } } Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); switch (msg.what) { case SCROLL_ACTION: int curPos = mGallery.getSelectedItemPosition(); if (curPos < mGalleryAdapter.getCount() - 1) { curPos++; } else { curPos = 0; } /* mGallery.setLayoutAnimation(new LayoutAnimationController( AnimationUtils.loadAnimation(HomeActivity.this, R.anim.gallery_in)));*/ mGallery.setSelection(curPos, true); /*MotionEvent e1 = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 89.333336f, 265.33334f, 0); MotionEvent e2 = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 300.0f, 238.00003f, 0); mGallery.onFling(e1, e2, -1300, 0);*/ break; default: break; } } }; }
实现图片定时自动切换和手动滑动切换。
相关文章推荐
- Android自定义View实现图片显示,并实现缩放、拖拽、切换功能
- TextView显示Html类解析的网页和图片及自定义标签
- 自定义view封装-用Button显示商品图片和名称
- Android可以动态控制图片显示区域的自定义ImageView
- 安卓自定义View——PictureGuide一款不错的图片导航,可实现图片显示滑动到哪一张
- TextView显示Html类解析的网页和图片及自定义标签
- xcode6.1 自定义tabbar与poptoview产生重叠问题以及ios8上自定义tabbar图片显示颜色是系统颜色问题
- android自定义View实现图片上传进度显示(仿手机QQ上传效果)
- 安卓自定义View实现图片上传进度显示(仿QQ)
- 使用自定义的item、Adapter和AsyncTask、第三方开源框架PullToRefresh联合使用实现自定义的下拉列表(从网络加载图片显示在item中的ImageView)
- Android自定义surfaceView显示多张图片
- 自定义ImageView显示gif图片
- 自定义View——图片指示器
- android自定义View实现图片上传进度显示(仿手机QQ上传效果)
- TextView显示Html类解析的网页和图片及自定义标签
- android:自定义imageview,可显示网络图片
- MCProgressView 使用自定义图片做进度显示
- ios 地图大头针自定义显示图片 MKAnnotationView
- android中使用自定义View让图片像画卷一样被展开显示
- 自定义View实现图片上传进度显示