这一次作为菜鸟,我要带你从零开始搭建一个APP,当然是仿照的,而且没有后台的,自己刚入门,对后台这块比较陌生,只能小打小闹,做做布局而已,若读者是菜鸟级别,我们倒是可以相互切磋,老鸟不喜勿喷
。
首先看看我们要仿照的APP界面
可以第一次登录的时候有个雷达效果,两个按钮--注册和登录,分别点击的时候有界面的跳转。
分析完了界面之后就带大家来实现以下这样的效果。首先看下长得比较丑的Demo效果,自定义VIew实现扫描
关于这个圆环扫描界面的实现主要是参考张鸿洋的博文而来,在此对作者表示感谢,同时附上博文地址
《Android 自定义View (三) 圆环交替 等待效果》http://blog.csdn.net/lmj623565791/article/details/24500107
对于想入门android自定义VIew的同学来说,鸿洋的文章真的很大,我这个界面的重点知识就是自定义VIew,如果游兴趣的同学可以参考下我的写法。
public class RadarView extends View { private Paint mPaint; // 画笔 private int mForeColor; // 前景颜色 private int mBackColor; // 背景颜色 private int mRadius; // 半径 private int mCenterImageResId; // 中间图片的资源ID private int mSpeed; // 扫描的速度 private final static int DEFAULT_SPEED = 10; private final static int DEFAULT_RADIUS = 20; private int mCurrentIndex; // 扫描的当前的位置 private BitmapShader mBitmapShader; public RadarView(Context context) { this(context, null); } public RadarView(Context context, AttributeSet attrs) { this(context, attrs, 0); // 调用三个参数的构造方法 } public RadarView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // 在这个构造方法里面获取属性值 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RadarView, defStyleAttr, 0); // 遍历属性列表 for (int i = 0; i < typedArray.getIndexCount(); i++) { int attr = typedArray.getIndex(i); // 得到属性值 // 将各自的属性值对号入座 switch (attr) { case R.styleable.RadarView_radarForeColor: mForeColor = typedArray.getColor(attr, Color.BLUE); break; case R.styleable.RadarView_radarBackColor: mBackColor = typedArray.getColor(attr, Color.WHITE); break; case R.styleable.RadarView_radarRadius: mRadius = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, DEFAULT_RADIUS, getResources().getDisplayMetrics())); break; case R.styleable.RadarView_radarCenterImageResId: mCenterImageResId = typedArray.getResourceId(attr, R.mipmap.ic_launcher); break; case R.styleable.RadarView_radarSpeed: mSpeed = typedArray.getInteger(attr, DEFAULT_SPEED); break; } } new Thread(new Runnable() { @Override public void run() { while (true){ mCurrentIndex += 2 ; if (mCurrentIndex == 360) { mCurrentIndex = 0; } postInvalidate(); try { Thread.sleep(mSpeed); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint = new Paint(); mPaint.setAntiAlias(true); int cx = getWidth() / 2; int radius = cx - mRadius/2 ; mPaint.setStrokeWidth(mRadius); mPaint.setColor(mBackColor); mPaint.setStyle(Paint.Style.FILL); canvas.drawCircle(cx, cx, radius, mPaint); mPaint.setColor(mForeColor); RectF oval = new RectF(cx - radius, cx - radius, cx + radius, cx + radius); canvas.drawArc(oval, -90, mCurrentIndex, true , mPaint); RectF bitmapRect = new RectF(cx - 80 , cx - 80 , cx + 80 , cx + 80); mPaint.setColor(Color.WHITE); canvas.drawCircle(bitmapRect.centerX() , bitmapRect.centerY() , 80 , mPaint); Bitmap bitmap = BitmapFactory.decodeResource(getResources(),mCenterImageResId); mPaint.setAntiAlias(true); mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint.setShader(mBitmapShader); canvas.drawBitmap(bitmap , null , bitmapRect , null); } }注意:在XML布局中使用自定义VIew的时候默认是调用两个参数的构造方法,也就是在这里默认会调用
RadarView(Context context, AttributeSet attrs)
这里整个画图和绘制的实现我们是在三个参数的构造方法中完成的,所以让两个参数的构造方法实现三个参数的构造方法就好了,
this(context, attrs, 0); // 调用三个参数的构造方法
这点很重要,如果你愿意,其实你也可以直接在两个参数的构造器中去绘制和实现功能;
这里我在VIew的中间化了一个Bitmap,就是图中那个圆形的风车图片
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),mCenterImageResId);
mPaint.setAntiAlias(true);
mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(mBitmapShader);
canvas.drawBitmap(bitmap , null , bitmapRect , null);
在Values文件夹下新建一个attrs.xml文件,用来存储要用到的一些属性声明
<?xml version="1.0" encoding="utf-8"?> <resources> <!--自定义雷达View需要的一些属性值--> <declare-styleable name="RadarView"> <attr name="radarForeColor" format="color"/> <attr name="radarBackColor" format="color"/> <attr name="radarCenterImageResId" format="reference"/> <attr name="radarSpeed" format="integer"/> <attr name="radarRadius" format="dimension"/> </declare-styleable> </resources>
然后在 activity_main.xml中添加我们刚刚自定义的View
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:cjt="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:gravity="center_horizontal" tools:context="com.cjt.tantandemo.MainActivity"> <com.cjt.tantandemo.view.RadarView android:id="@+id/mRadarView" android:layout_width="300dp" cjt:radarForeColor="@color/colorPrimary" cjt:radarBackColor="@color/colorAccent" cjt:radarSpeed="20" cjt:radarRadius="100dp" cjt:radarCenterImageResId="@mipmap/windmill" android:layout_height="250dp" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" /> <Button android:id="@+id/register_btn" android:layout_marginTop="15dp" android:layout_width="120dp" android:text="@string/login_btn" android:layout_height="wrap_content" android:layout_below="@+id/login_btn" android:layout_centerHorizontal="true" android:layout_alignLeft="@+id/login_btn" android:layout_alignStart="@+id/login_btn" /> <Button android:id="@+id/login_btn" android:text="@string/register_btn" android:layout_marginTop="15dp" android:layout_width="120dp" android:layout_height="wrap_content" android:layout_below="@+id/mRadarView" android:layout_centerHorizontal="true" /> </RelativeLayout>
直接运行就可以看到我们图中的效果了,至于两个按钮的点击和跳转相信难不倒大家,所以这里我就不重点拿出来写了,源码等完成了整个项目的模仿在上传。又需要的可以留言。