1
spinner_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="60dp" />
<ImageView
android:id="@+id/iv_arrow"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentRight="true"
android:src="@drawable/down_arrow"/>
</RelativeLayout>
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import java.util.ArrayList;
public class SpinnerView extends RelativeLayout{
private EditText et;
private ImageView ivArrow;
private ArrayList<String> mData;
private ArrayAdapter<String> adapter;
private PopupWindow popupWindow;
public SpinnerView(Context context, AttributeSet attrs) {
super(context, attrs);
View view = LayoutInflater.from(context).inflate(R.layout.spinner_view, null);
addView(view);
initData();
initView(view);
}
private void initData() {
mData = new ArrayList<>();
for (int i = 0; i < 30; i++) {
mData.add("秋裤:"+i);
}
}
private void initView(View view) {
et = view.findViewById(R.id.et);
ivArrow = view.findViewById(R.id.iv_arrow);
ivArrow.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
pop();
}
});
}
private void pop() {
if (popupWindow==null){
ListView listView = new ListView(getContext());
adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_expandable_list_item_1, mData);
listView.setAdapter(adapter);
listView.setBackgroundResource(R.drawable.listview_background);
popupWindow = new PopupWindow(listView, et.getWidth(), 700);
popupWindow.setBackgroundDrawable(new ColorDrawable());
popupWindow.setOutsideTouchable(true);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
popupWindow.dismiss();
et.setText(mData.get(position));
et.setSelection(mData.get(position).length());
}
});
}
popupWindow.showAsDropDown(et);
}
}
1.gif
2
package com.example.lenovo.day11;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
public class MyView extends View{
private final int mStartX;
private final int mStartY;
private final int mEndX;
private final int mEndY;
private final Paint paint;
private final Paint mCirclePanit;
private final Bitmap mBitmap;
private final Path mPath;
private final RectF mRectF;
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
// 1、画直线
mStartX = 50;
mStartY = 50;
mEndX = 200;
mEndY = 200;
paint = new Paint();
paint.setColor(Color.parseColor("#FFFFFF"));
paint.setStrokeWidth(5);
paint.setAntiAlias(true);
// 3、画空心圆
mCirclePanit = new Paint();
mCirclePanit.setColor(Color.parseColor("#FFFFFF"));
mCirclePanit.setStrokeWidth(5);
mCirclePanit.setAntiAlias(true);
mCirclePanit.setStyle(Paint.Style.STROKE);
// 4、画图片
mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.c);
// 5、画三角形(多边形)
int x1 = 50;
int y1 = 50;
int x2 = 700;
int y2 =80;
int x3 = 360;
int y3 = 650;
mPath = new Path();
mPath.moveTo(x1,y1);
mPath.lineTo(x2,y2);
mPath.lineTo(x3,y3);
mPath.lineTo(x1,y1);
// 7、画扇形
mRectF = new RectF(50, 50, 720, 720);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 6、裁剪 (先裁切再画别的东西,比如图片)
// canvas.clipPath(mPath);
// 1、画直线
// canvas.drawLine(mStartX,mStartY,mEndX,mEndY,paint);
// 2、画圆
// canvas.drawCircle(200,200,50,paint);
// 3、画空心圆
// canvas.drawCircle(200,200,50,mCirclePanit);
// 4、画图片
// canvas.drawBitmap(mBitmap,50,50,mCirclePanit);
// 5、画三角形(多边形)
// canvas.drawPath(mPath,mCirclePanit);
// 7、画扇形
//startAngle 其实角度,水平向右0度
//sweepAngle 夹角
//useCenter true,实心的扇形
canvas.drawArc(mRectF,0,120,false,mCirclePanit);
}
}
3
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class BallView extends View{
private final Bitmap bitmap;
private final Paint paint;
private float mLeft;
private float mTop;
public BallView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ball);
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(bitmap,mLeft,mTop,paint);
}
/**
* 触摸事件,在这里获取手指触摸的位置,然后小球重新绘制到对应位置就可以了
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
mLeft = event.getX();
mTop = event.getY();
//重新绘制
invalidate();
//滑动的时候这个方法消费触摸事件
return true;
}
}
3.gif
4、圆形进度条
圆形进度条.gif1、在res文件夹下的values文件中创建attrs.xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--declare-styleable name="CircleProgress" 加了name之后,标签中的属性就可以直接给CircleProgress-->
<declare-styleable name="CircleProgress">
<!--自定义的属性-->
<!-- format 属性值的类型 color 颜色 reference 关联类型-->
<attr name="ring_color" format="reference|color"/>
<attr name="ring_width" format="dimension"/>
<!--起始角度-->
<attr name="startAngle" format="float"/>
<attr name="sweepAngle" format="float"/>
<attr name="circle_color" format="reference|color"/>
<!--使用系统的属性-->
<attr name="android:textColor"/>
<attr name="android:text"/>
<attr name="android:textSize"/>
</declare-styleable>
</resources>
2、在Activity对应的xml文件中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<com.example.circleprogressbar.CircleProgress
app:ring_width="12dp"
app:ring_color="@color/colorAccent"
app:circle_color="@color/colorPrimary"
app:startAngle="-90"
app:sweepAngle="0"
android:textColor="@color/colorAccent"
android:text="0%"
android:textSize ="20sp"
android:id="@+id/cp"
android:background="#cecece"
android:layout_width="300dp"
android:layout_height="300dp" />
<Button
android:id="@+id/btn"
android:text="开始下载"
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
3、创建一个CircleProgress类并继承View
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
* @author
* Created by asus on 2019/4/15.
* a.自定义一个CustomView(extends View )类
b.编写values/attrs.xml,在其中编写styleable和item等标签元素
c.在布局文件中CustomView使用自定义的属性(注意namespace)
导入自定义属性,以下两种方式都可(namespace)
http://schemas.android.com/apk/res/包名
http://schemas.android.com/apk/res-auto
d.在CustomView的构造方法中通过TypedArray获取
xmlns:app="http://schemas.android.com/apk/res-auto" 命名空间 xml name space
*/
public class CircleProgress extends View{
private static final String TAG = "CircleProgress";
private float mSweepAngle;
private float mRingWidth;
private int mRingColor;
private float mStartAngle;
private int mTextColor;
private String mText;
private float mTextSize;
private RectF mRectF;
private Paint mRingPaint;
private int mCx;
private int mCy;
private int mRadius;
private int mCircleColor;
private Paint mCirclePaint;
private Paint mTextPaint;
private float mDy;
public CircleProgress(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
//获取设置的属性
int attributeCount = attrs.getAttributeCount();
//开发有时候不用这种,因为关联类型的获取出来是资源id,一般TypedArray
/* for (int i = 0; i < attributeCount; i++) {
String attributeName = attrs.getAttributeName(i);
String attributeValue = attrs.getAttributeValue(i);
Log.d(TAG, "attributeName: "+attributeName+",value:"+attributeValue);
}*/
//TypedArray
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgress);
if (ta != null) {
mRingWidth = ta.getDimension(R.styleable.CircleProgress_ring_width, 20);
mRingColor = ta.getColor(R.styleable.CircleProgress_ring_color, 0);
mStartAngle = ta.getFloat(R.styleable.CircleProgress_startAngle, -90);
mSweepAngle = ta.getFloat(R.styleable.CircleProgress_sweepAngle, 0);
mTextColor = ta.getColor(R.styleable.CircleProgress_android_textColor, 0);
mCircleColor = ta.getColor(R.styleable.CircleProgress_circle_color, 0);
mText = ta.getString(R.styleable.CircleProgress_android_text);
mTextSize = ta.getDimension(R.styleable.CircleProgress_android_textSize, 20);
//#ffffff--->int
Log.d(TAG, "textcolor: " + mRingColor);
//释放资源
ta.recycle();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int max = Math.max(width, height);
mCx = max/2;
mCy = mCx;
mRadius = max/4;
//防止有人给弄成长方形的
int widthHeigth = MeasureSpec.makeMeasureSpec(max, MeasureSpec.EXACTLY);
super.onMeasure(widthHeigth, widthHeigth);
//环
mRectF = new RectF(0.1f*max, 0.1f*max, 0.9f*max, 0.9f*max);
mRingPaint = new Paint();
mRingPaint.setColor(mRingColor);
mRingPaint.setAntiAlias(true);
mRingPaint.setStyle(Paint.Style.STROKE);
mRingPaint.setStrokeWidth(mRingWidth);
//内圆
mCirclePaint = new Paint();
mCirclePaint.setColor(mCircleColor);
mCirclePaint.setAntiAlias(true);
//文本
mTextPaint = new Paint();
mTextPaint.setColor(mTextColor);
mTextPaint.setTextSize(mTextSize);
//水平居中
mTextPaint.setTextAlign(Paint.Align.CENTER);
//垂直居中需要向下移动center线到baseline线的距离
Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
float textHeight = fontMetrics.descent - fontMetrics.ascent;
mDy = textHeight / 2 - fontMetrics.descent;
}
@Override
protected void onDraw(Canvas canvas) {
//1.先画环
canvas.drawArc(mRectF,mStartAngle,mSweepAngle,false,mRingPaint);
//2.画内圆
canvas.drawCircle(mCx,mCy,mRadius,mCirclePaint);
//3.文本,文本不是从给定点的左上角开始写的,而是要对齐baseline,所以文本靠右上角
//canvas.drawText(mText,mCx,mCy,mTextPaint);
//canvas.drawText(mText,mCx,mCy+(center线到Baseline的距离),mTextPaint);
canvas.drawText(mText,mCx,mCy+mDy,mTextPaint);
}
/**
* 设置进度
* @param progress 0--100
*/
public void setProgress(int progress) {
mText = progress+" %";
mSweepAngle = progress * 360 * 1.0f/100;
//重新绘制
//invalidate();
//非ui线程调用这个方法
postInvalidate();
}
public float getmSweepAngle() {
return mSweepAngle;
}
}
4、在Acticity中
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private CircleProgress cp;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
cp = (CircleProgress) findViewById(R.id.cp);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn:
down();
break;
}
}
private void down() {
if (cp.getmSweepAngle()==0){
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
try {
Thread.sleep(300);
cp.setProgress(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}else {
Toast.makeText(this, "正在下载中,请稍后", Toast.LENGTH_SHORT).show();
}
}
}
网友评论