PK界面
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00000000"
android:paddingLeft="12dp"
android:paddingRight="12dp" >
<com.bqt.pk.StrokeTextView
android:id="@+id/tv_total_fire"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:drawableTop="@drawable/live_pk"
android:ellipsize="end"
android:singleLine="true"
android:text="PK火力:100"
android:textColor="#ffe500"
android:textSize="10sp" />
<ProgressBar
android:id="@+id/pb_left"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="14dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toLeftOf="@id/tv_total_fire"
android:max="100"
android:progress="50"
android:progressDrawable="@drawable/pk_progress_left" />
<ImageView
android:id="@+id/iv_head_left"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/bg_live_pk_head"
android:padding="1dp"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/tv_this_live"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="2dp"
android:layout_toRightOf="@id/iv_head_left"
android:ellipsize="end"
android:singleLine="true"
android:text="包青天"
android:textColor="#000"
android:textSize="9sp"
android:visibility="visible" />
<TextView
android:id="@+id/tv_fire_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="8dp"
android:layout_toRightOf="@id/iv_head_left"
android:ellipsize="end"
android:gravity="center"
android:shadowColor="#000"
android:shadowDx="0"
android:shadowDy="1"
android:shadowRadius="2"
android:singleLine="true"
android:text="0火力"
android:textColor="#fff"
android:textSize="10sp" />
<TextView
android:id="@+id/tv_fire_add_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/tv_fire_left"
android:ellipsize="end"
android:gravity="center"
android:shadowColor="#c000"
android:shadowDx="0"
android:shadowDy="1"
android:shadowRadius="4"
android:singleLine="true"
android:text="+9999"
android:textColor="#ffe500"
android:textSize="10sp"
android:visibility="gone" />
<ImageView
android:id="@+id/iv_win_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="36dp"
android:src="@drawable/live_pk_success"
android:visibility="invisible" />
<ProgressBar
android:id="@+id/pb_right"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="14dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
android:layout_toRightOf="@id/tv_total_fire"
android:max="100"
android:progress="10"
android:progressDrawable="@drawable/pk_progress_right" />
<ImageView
android:id="@+id/iv_head_right"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/bg_live_pk_head"
android:padding="1dp"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/tv_fire_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@+id/iv_head_right"
android:ellipsize="end"
android:gravity="center"
android:shadowColor="#000"
android:shadowDx="0"
android:shadowDy="1"
android:shadowRadius="2"
android:singleLine="true"
android:text="0火力"
android:textColor="#fff"
android:textSize="10sp" />
<TextView
android:id="@+id/tv_fire_add_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/tv_fire_right"
android:ellipsize="end"
android:gravity="center"
android:shadowColor="#c000"
android:shadowDx="0"
android:shadowDy="1"
android:shadowRadius="4"
android:singleLine="true"
android:text="999999+"
android:textColor="#ffe500"
android:textSize="10sp"
android:visibility="gone" />
<ImageView
android:id="@+id/iv_win_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="36dp"
android:src="@drawable/live_pk_success"
android:visibility="invisible" />
</RelativeLayout>
<com.bqt.pk.StrokeTextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="#00000000"
android:gravity="center"
android:text="剩余时间99"
android:textColor="#fff"
android:textSize="10sp" />
</merge>
图片背景资源
给头像加一个圆框 bg_live_pk_head.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<stroke
android:width="1dp"
android:color="#ff00" />
<solid android:color="#0000" />
</shape>
进度条背景 pk_progress_left.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/background">
<nine-patch
android:dither="true"
android:src="@drawable/live_pk_progress_left_bg" />
</item>
<item android:id="@android:id/progress">
<clip
android:clipOrientation="horizontal"
android:gravity="left" >
<nine-patch
android:dither="true"
android:src="@drawable/live_pk_progress_left" />
</clip>
</item>
</layer-list>
进度条背景 pk_progress_right.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/background">
<nine-patch
android:dither="true"
android:src="@drawable/live_pk_progress_right_bg" />
</item>
<item android:id="@android:id/progress">
<clip
android:clipOrientation="horizontal"
android:gravity="end" >
<nine-patch
android:dither="true"
android:src="@drawable/live_pk_progress_right" />
</clip>
</item>
</layer-list>
代码-Activity
public class MainActivity extends Activity {
private EditText et_num;
private PkView pk_view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et_num = (EditText) findViewById(R.id.et_num);
pk_view = (PkView) findViewById(R.id.pk_view);
}
public void add_left(View view) {
String content = et_num.getText().toString().trim();
if (!TextUtils.isEmpty(content)) {
int addFire = Integer.parseInt(content);//增加的进度值
pk_view.addPkFire(true, addFire);
}
}
public void add_right(View view) {
String content = et_num.getText().toString().trim();
if (!TextUtils.isEmpty(content)) {
int addFire = Integer.parseInt(content);//增加的进度值
pk_view.addPkFire(false, addFire);
}
}
}
代码-PKView
public class PkView extends LinearLayout {
private ImageView iv_head_left;//左头像
private ImageView iv_head_right;//右头像
private ImageView iv_win_left;//左赢
private ImageView iv_win_right;//右赢
private ProgressBar pb_left;//左进度
private ProgressBar pb_right;//右进度
private TextView tv_fire_left;//左火力
private TextView tv_fire_right;//右火力
private TextView tv_fire_add_left;//左增加火力
private TextView tv_fire_add_right;//右增加火力
private StrokeTextView tv_total_fire;//中间pk的火力
private StrokeTextView tv_time;//中间pk剩余时间
private int remainTime = 60;//倒计时
private Handler mHandler;
private boolean isOver = false;//是否到时间了或已经有人胜了
private Context mContext;
private Bitmap mBitmap;//头像
private int leftFife;//左进度值private int rightFife;//右进度值
private final int totalFire = 100;//总进度值
public PkView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
public PkView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PkView(Context context) {
this(context, null);
}
private void initView(Context context) {
mContext = context;
setOrientation(LinearLayout.VERTICAL);//要在代码中设置这个东东
LayoutInflater.from(mContext).inflate(R.layout.live_pk, this, true);
iv_head_left = (ImageView) findViewById(R.id.iv_head_left);
iv_head_right = (ImageView) findViewById(R.id.iv_head_right);
iv_win_left = (ImageView) findViewById(R.id.iv_win_left);
iv_win_right = (ImageView) findViewById(R.id.iv_win_right);
pb_left = (ProgressBar) findViewById(R.id.pb_left);
pb_right = (ProgressBar) findViewById(R.id.pb_right);
tv_fire_left = (TextView) findViewById(R.id.tv_fire_left);
tv_fire_right = (TextView) findViewById(R.id.tv_fire_right);
tv_fire_add_left = (TextView) findViewById(R.id.tv_fire_add_left);
tv_fire_add_right = (TextView) findViewById(R.id.tv_fire_add_right);
tv_total_fire = (StrokeTextView) findViewById(R.id.tv_total_fire);
tv_time = (StrokeTextView) findViewById(R.id.tv_time);
//初始值
pb_left.setProgress(0);
pb_right.setProgress(0);
tv_total_fire.setText("PK火力 " + totalFire);
tv_time.setText(remainTime + "秒后截止");
//设置描边
tv_time.setStrokeColorAndWidth(0x7f000000, 2);
tv_total_fire.setStrokeColorAndWidth(0x7fff0000, 1.5f);//木有效果,若去掉android:gravity且不设置setGravity就可以!
tv_total_fire.setGravity(Gravity.CENTER);
//**************************************************************************************************************************
//设置圆角图片[并不带边框]
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img_user_icon);
int min = Math.min(mBitmap.getWidth(), mBitmap.getHeight());
final Paint paint = new Paint();
paint.setAntiAlias(true);//抗锯齿
Bitmap target = Bitmap.createBitmap(min, min, Config.ARGB_8888);
Canvas canvas = new Canvas(target);//产生一个同样大小的画布
canvas.drawCircle(min / 2, min / 2, min / 2, paint); //先绘制圆形
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//使用SRC_IN
canvas.drawBitmap(mBitmap, 0, 0, paint);//后绘制图片
iv_head_left.setImageBitmap(target);
iv_head_right.setImageResource(R.drawable.ic_launcher);
//计时器
if (mHandler == null) {
mHandler = new Handler() {
public void handleMessage(Message msg) {
if (remainTime > 0) {
if (!isOver) {
tv_time.setText(--remainTime + "秒后截止");
mHandler.sendEmptyMessageDelayed(0, 1000);
} else {
isOver = true;
mHandler.removeCallbacksAndMessages(null);//If token is null, all callbacks and messages will be removed
new AlertDialog.Builder(mContext).setMessage("恭喜,***取胜了").create().show();
PkView.this.setVisibility(View.GONE);//隐藏掉
}
} else {
mHandler.removeCallbacksAndMessages(null);
new AlertDialog.Builder(mContext).setMessage("很遗憾,时间到了,木有人取胜").create().show();
PkView.this.setVisibility(View.GONE);
}
};
};
}
mHandler.sendEmptyMessageDelayed(0, 1000);//1秒后发送空消息
}
/**
* 增加pk火力值
* @param which true为左边,false为右边
* @param num 增加了多少火力
*/
public void addPkFire(boolean which, int num) {
if (which) {
leftFife = leftFife + num;
pb_left.setProgress(leftFife * 100 / totalFire);
tv_fire_left.setText(leftFife + "火力");
if (totalFire - leftFife > 0) playAddAnimate(true, num);
else {
playWinAnimate(true);
isOver = true;
}
} else {
rightFife = rightFife + num;
pb_right.setProgress(rightFife * 100 / totalFire);
tv_fire_right.setText(rightFife + "火力");
if (totalFire - rightFife > 0) playAddAnimate(false, num);
else {
playWinAnimate(false);
isOver = true;
}
}
}
/**
* 播放增加火力动画
* @param which true为左边,false为右边
* @param num 增加了多少火力
*/
private void playAddAnimate(boolean which, int num) {
final TextView targeTextView;
final float animateY = dip2px(mContext, 15);//Y轴初始位置,直接设为15是不合适的,应该提供一个方法供外部修改
if (which) {
targeTextView = tv_fire_add_left;
targeTextView.setText(" +" + num);
} else {
targeTextView = tv_fire_add_right;
targeTextView.setText(num + "+ ");
}
ObjectAnimator translationYAnimator = ObjectAnimator.ofFloat(targeTextView, "translationY", 0, -animateY);
ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(targeTextView, "alpha", 0, 1, 0);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(1000);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
targeTextView.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
targeTextView.setVisibility(View.INVISIBLE);
}
});
animatorSet.playTogether(translationYAnimator, alphaAnimator);
animatorSet.start();
}
/**
* 播放赢动画
* @param which true为左边,false为右边
*/
private void playWinAnimate(boolean which) {
if (PkView.this.getVisibility() != View.VISIBLE) return;
final ImageView targeImageView;
if (which) targeImageView = iv_win_left;
else targeImageView = iv_win_right;
ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(targeImageView, "scaleX", 1.6F, 1);
ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(targeImageView, "scaleY", 1.6F, 1);
ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(targeImageView, "alpha", 0, 1);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(250);
animatorSet.setInterpolator(new DecelerateInterpolator());//由快变慢
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
targeImageView.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
if (mHandler != null) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
PkView.this.setVisibility(View.GONE);//隐藏掉
}
}, 8000);
}
}
});
animatorSet.playTogether(scaleXAnimator, scaleYAnimator, alphaAnimator);
animatorSet.start();
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static float dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return dpValue * scale + 0.5f;
}
}
代码-带描边的TextView
/*
* 给文字加描边,实现方法是两个TextView叠加,只有描边的TextView为底,实体TextView叠加在上面
*/
public class StrokeTextView extends TextView {
private TextView strokeTextView = null;//描边
private int strokeColor = 0xffff0000;//描边的TextView的颜色
private float strokeWidth = 1.5f;//描边的TextView的宽度
/**
* 设置描边的颜色和宽度
*/
public void setStrokeColorAndWidth(int strokeColor, float strokeWidth) {
this.strokeColor = strokeColor;
this.strokeWidth = strokeWidth;
init();//必须重新调用初始化方法
}
//**********************************************************************************************
public StrokeTextView(Context context) {
this(context, null);
}
public StrokeTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public StrokeTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
strokeTextView = new TextView(context, attrs, defStyle);
init();
}
public void init() {
TextPaint textPaint = strokeTextView.getPaint();
textPaint.setStrokeWidth(strokeWidth); //设置描边宽度
strokeTextView.setTextColor(strokeColor); //设置描边颜色
textPaint.setStyle(Style.STROKE); //对文字只描边
invalidate();
}
//**************************************************************************************************************************
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
strokeTextView.setText(getText());
strokeTextView.setGravity(getGravity());
strokeTextView.measure(widthMeasureSpec, heightMeasureSpec);
}
@Override
//卧槽,为啥必须把super放在后面?
protected void onDraw(Canvas canvas) {
strokeTextView.draw(canvas);
super.onDraw(canvas);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
strokeTextView.layout(left, top, right, bottom);
}
@Override
public void setLayoutParams(ViewGroup.LayoutParams params) {
super.setLayoutParams(params);
strokeTextView.setLayoutParams(params);
}
@Override
public void setBackgroundResource(int resid) {
super.setBackgroundResource(resid);
strokeTextView.setBackgroundResource(resid);
}
@Override
public void setTextSize(float size) {
super.setTextSize(size);
strokeTextView.setTextSize(size);
}
@Override
public void setTextSize(int unit, float size) {
super.setTextSize(unit, size);
strokeTextView.setTextSize(unit, size);
}
}