Android之自定义View
2016-07-23 19:08
591 查看
本文主要是记录一些零碎的东西
项目地址:https://github.com/CL-window/MyView
1 . 实现三个button ,可以左右滑动(动画效果),中间的一个突出显示(放大)
其实没啥,就是监听了滑动事件,只是动画太丑
2. progressbar 实现一个计时器,计时完成做相应的动作
代码:
activity里 ((MyProgressBar)findViewById(R.id.progress)).setMax(20);
3. seekBar 动画显示当前进度
看看自定义的view
项目地址:https://github.com/CL-window/MyView
1 . 实现三个button ,可以左右滑动(动画效果),中间的一个突出显示(放大)
其实没啥,就是监听了滑动事件,只是动画太丑
/** * <p>Description: 中间突出的滑动 button </p> * Created by slack on 2016/7/11 11:00 . * 动画添加失败,以后再处理 */ public class showCenter extends LinearLayout implements View.OnClickListener { private double downX,upX; private double threshold = 30;// 滑动阈值 private int[] smallIco = {R.drawable.video,R.drawable.camera,R.drawable.gifp};// 小图 录像 拍照 gif private int[] bigIco = {R.drawable.video_large,R.drawable.camera_large,R.drawable.gifp_large};// 录像 拍照 gif private String[] bigIcoInfo = {"录像", "拍照", "GIF"}; private int centerSelect = 1; private View view; private ImageView leftImage,centerImage,rightImage,tempImage; private TextView centerInfo; private ShowCenterListener mShowCenterListener; public showCenter(Context context) { super(context); } public showCenter(Context context, AttributeSet attrs) { super(context, attrs); // setWillNotDraw(false);// 关于onDraw()方法不被执行的解决方法 view = LayoutInflater.from(context).inflate(R.layout.bottomview, this); initView(); initListener(); } private void initView() { leftImage = (ImageView) view.findViewById(R.id.bottom_view_left); centerImage =(ImageView) view.findViewById(R.id.bottom_view_center_big); rightImage = (ImageView)view.findViewById(R.id.bottom_view_right); centerInfo = (TextView)view.findViewById(R.id.bottom_view_center_info); } private void initListener() { view.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction()){ case MotionEvent.ACTION_DOWN: downX = motionEvent.getX(); // Log.i("slack","ACTION_DOWN..."+downX); break; case MotionEvent.ACTION_MOVE: // Log.i("slack","ACTION_MOVE..."); // 滑动中开始动画 break; case MotionEvent.ACTION_UP: upX = motionEvent.getX(); // Log.i("slack","ACTION_UP..."+upX); if(downX - upX > threshold){ Log.i("slack","left...1"); leftSelect(); }else if(upX - downX > threshold){ Log.i("slack","right...1"); rightSelect(); } // invalidate();// changeView(); break; default: break; } return true; } }); leftImage.setOnClickListener(this); centerImage.setOnClickListener(this); rightImage.setOnClickListener(this); centerInfo.setOnClickListener(this); } private void leftSelect() { if(centerSelect > 2 ){ centerSelect = 0; } centerSelect = (centerSelect + 1) % 3; startAnim(); } private void startAnim() { animCreate(leftImage); animCreate(centerImage); animCreate(rightImage); } private void rightSelect() { if(centerSelect < 0){ centerSelect = 2; } centerSelect = (centerSelect + 2) % 3; startAnim(); } public AnimatorSet animCreate(ImageView imageView){ AnimatorSet animatorSet = new AnimatorSet(); ObjectAnimator oaX = ObjectAnimator.ofFloat(imageView, "scaleX", 0.5f, 1f); ObjectAnimator oaY = ObjectAnimator.ofFloat(imageView, "scaleY", 0.5f, 1f); ObjectAnimator oaA = ObjectAnimator.ofFloat(imageView, "alpha", 0.0f, 1f); animatorSet.play(oaX).with(oaY).with(oaA); animatorSet.setDuration(800); animatorSet.setInterpolator(new OvershootInterpolator()); // animatorSet.setStartDelay(300); animatorSet.start(); return animatorSet; } private void changeView() { leftImage.setImageResource(smallIco[(centerSelect + 2) % 3]); centerImage.setImageResource(bigIco[centerSelect % 3]); centerInfo.setText(bigIcoInfo[centerSelect]); rightImage.setImageResource(smallIco[(centerSelect + 1) % 3]); if(mShowCenterListener != null) { mShowCenterListener.onSliding(centerSelect); } } public showCenter(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { Log.i("slack","onLayout...3"); super.onLayout(changed, left, top, right, bottom); } @Override protected void onDraw(Canvas canvas) { Log.i("slack","onDraw...4"); super.onDraw(canvas); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Log.i("slack","onMeasure...2"); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.bottom_view_left: rightSelect(); changeView(); break; case R.id.bottom_view_center_big: case R.id.bottom_view_center_info: if(mShowCenterListener != null){ mShowCenterListener.onCenterClick(); } break; case R.id.bottom_view_right: leftSelect(); changeView(); break; default: break; } } // 设置监听 public void setListener(ShowCenterListener showCenterListener){ mShowCenterListener = showCenterListener; } interface ShowCenterListener{ void onSliding(int mode);// 滑动监听 提供当前中间的按钮模式 ( 0:录像 1:拍照 2:gif) void onCenterClick();// 点击中间的按钮(拍照或者gif或者录像) 监听 } }
2. progressbar 实现一个计时器,计时完成做相应的动作
代码:
/** * <p>Description: 自定义 ProgressBar ,倒计时效果,</p> * Created by slack on 2016/7/12 15:16 . */ public class MyProgressBar extends LinearLayout { private ProgressBar mProgressBar; private Handler mHandler; private int maxTime = 0; private ProgressListener mProgressListener; public MyProgressBar(Context context) { super(context); } public MyProgressBar(Context context, AttributeSet attrs) { super(context, attrs); mProgressBar = (ProgressBar)LayoutInflater.from(context).inflate(R.layout.progressbar, this).findViewById(R.id.progressBar); mHandler = new Handler(); } public MyProgressBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } /** * * @param maxTime 时间(秒) */ public void setMax(int maxTime) { this.maxTime = maxTime; mProgressBar.setProgress(1); mProgressBar.setMax(maxTime); mHandler.post(timeCount); } Runnable timeCount = new Runnable() { @Override public void run() { // Log.i("slack","timeCount " + mProgressBar.getProgress() + "," + maxTime); if(mProgressBar.getProgress() < maxTime) { mProgressBar.incrementProgressBy(1); if(mProgressListener != null){ mProgressListener.progress(mProgressBar.getProgress()); } mHandler.postDelayed(timeCount, 1000); }else{ if(mProgressListener != null){ mProgressListener.finish(); } mHandler.removeCallbacks(timeCount); // Log.i("slack","timeCount finish..."); } } }; public interface ProgressListener{ void progress(int progress); void finish();// 计时完成操作,这个控件需要dismiss } }使用:布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.bigview.MainActivity"> <com.example.bigview.MyProgressBar android:id="@+id/progress" android:layout_width="match_parent" android:layout_height="20dp"></com.example.bigview.MyProgressBar> <!-- <com.example.bigview.showCenter android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Hello World!" />--> </LinearLayout>
activity里 ((MyProgressBar)findViewById(R.id.progress)).setMax(20);
3. seekBar 动画显示当前进度
看看自定义的view
import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.support.v7.widget.ActionBarOverlayLayout; import android.support.v7.widget.AppCompatSeekBar; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.OvershootInterpolator; import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.TextView; /** * <p>Description: </p> * Created by slack on 2016/7/18 13:14 . */ public class MySeekBar extends LinearLayout { private View view; private SeekBar mSeekBar; private SeekBarProgress mSeekBarProgress; private TextView proressInfo; private float progres = 0; public MySeekBar(Context context) { super(context); } public MySeekBar(Context context, AttributeSet attrs) { super(context, attrs); view = LayoutInflater.from(context).inflate(R.layout.seekbar, this); init(); } public MySeekBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private void init() { proressInfo = (TextView)view.findViewById(R.id.progress_info); mSeekBar = (SeekBar) view.findViewById(R.id.my_seekbar); changeInfoX(); mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean b) { // Log.i("slack","onProgressChanged:" + progress); progres = progress; proressInfo.setText( progress + "%"); animBig(proressInfo); if(mSeekBarProgress != null){ mSeekBarProgress.onSeekProgress(progress); } changeInfoX(); } @Override public void onStartTrackingTouch(SeekBar seekBar) { // Log.i("slack","onStartTrackingTouch..."); } @Override public void onStopTrackingTouch(SeekBar seekBar) { // Log.i("slack","onStopTrackingTouch..." +mSeekBar.getX() +","+ // (progres / 100) + "," + // mSeekBar.getWidth() + "," +mSeekBar.getMeasuredWidth() + ","+ // (proressInfo.getMeasuredWidth() / 2) + "," + // (mSeekBar.getMeasuredWidth() * (progres / 100) + mSeekBar.getX() )); // proressInfo 位置:progress点的位置上 changeInfoX(); animCreate(proressInfo); } }); } private void changeInfoX() { proressInfo.setX( mSeekBar.getMeasuredWidth() * (progres / 100) + mSeekBar.getX() - (proressInfo.getMeasuredWidth() / 2) ); } public AnimatorSet animCreate(View view){ AnimatorSet animatorSet = new AnimatorSet(); ObjectAnimator oaX = ObjectAnimator.ofFloat(view, "scaleX",0.5f, 1.0f, 0.5f); ObjectAnimator oaY = ObjectAnimator.ofFloat(view, "scaleY", 0.5f, 1.0f, 0.5f); ObjectAnimator oaA = ObjectAnimator.ofFloat(view, "alpha", 0.5f , 1.0f, 0.5f); animatorSet.play(oaX).with(oaY).with(oaA); animatorSet.setDuration(800); animatorSet.setInterpolator(new OvershootInterpolator()); // animatorSet.setStartDelay(100); animatorSet.start(); return animatorSet; } public AnimatorSet animBig(View view){ AnimatorSet animatorSet = new AnimatorSet(); ObjectAnimator oaX = ObjectAnimator.ofFloat(view, "scaleX",0.5f, 2.0f); ObjectAnimator oaY = ObjectAnimator.ofFloat(view, "scaleY", 0.5f, 2.0f); ObjectAnimator oaA = ObjectAnimator.ofFloat(view, "alpha", 0.5f , 1f); animatorSet.play(oaX).with(oaY).with(oaA); animatorSet.setDuration(0); animatorSet.setInterpolator(new OvershootInterpolator()); animatorSet.start(); return animatorSet; } public void setmSeekBarProgress(SeekBarProgress mSeekBarProgress) { this.mSeekBarProgress = mSeekBarProgress; } interface SeekBarProgress{ void onSeekProgress(int progress); } }布局文件 seekbar.xml
<?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" android:orientation="vertical"> <TextView android:id="@+id/progress_info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginBottom="5dp" android:background="@drawable/border_progress_info" /> <android.support.v7.widget.AppCompatSeekBar android:id="@+id/my_seekbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:minHeight="2dp" android:maxHeight="2dp" android:max="100" android:progress="20" android:progressDrawable="@drawable/bg_seekbar"/> </LinearLayout>
相关文章推荐
- 配置View桌面时找不到域的解决方法
- 完全克隆的虚拟桌面部署问题
- 实例讲解JavaScript的Backbone.js框架中的View视图
- Android中View自定义组合控件的基本编写方法
- Android 自定义View步骤
- Android自定义View仿QQ健康界面
- Android重写View实现全新的控件
- 解读ASP.NET 5 & MVC6系列教程(16):自定义View视图文件查找逻辑
- Android自定义View过程解析
- Android 自定义View 密码框实例代码
- Android自定义View软键盘实现搜索
- thinkphp3.x自定义Action、Model及View的简单实现方法
- codeigniter中view通过循环显示数组数据的方法
- MVVM模式中ViewModel和View、Model有什么区别?
- Android使用WindowManager构造悬浮view
- Android App开发中自定义View和ViewGroup的实例教程
- Android自定义View实现左右滑动选择出生年份
- Android应用开发中View绘制的一些优化点解析
- 自定义滑动按钮为例图文剖析Android自定义View绘制
- Android自定义View实现带数字的进度条实例代码