首先来看下今日头条效果图:
再来看下我们实现的效果:
实现思路,为了复用以及封装性,所以决定使用自定义ViewGroup来实现,下面来看实现代码:
这里是初始化布局,以及监听事件的方法:
/**
* 初始化布局
*/
private void initView() {
//获取外布局的宽高
int totalWidth = getMeasuredWidth();
int totalHeight = getMeasuredHeight();
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof Button) {
button = (Button) getChildAt(i);
//摆放子View,参数分别是子View矩形区域的左、上、右、下边
child.layout(0, 0, totalWidth, totalHeight);
}
if (getChildAt(i) instanceof ProgressBar) {
progressBar = (ProgressBar) getChildAt(i);
//摆放子View,参数分别是子View矩形区域的左、上、右、下边
child.layout(0, 0, totalWidth, totalHeight);
}
}
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if ("已关注".equals(button.getText().toString().trim())) {
return;
}
Message message = Message.obtain();
message.obj = "";
message.what = 2;
handler.sendMessage(message);
if (buttonClickListener != null) {
buttonClickListener.innerClick();
}
}
});
}
好了,其实这里开始还考虑到使用代码动态创建View然后layout上去,后来发现,这样的话需要定义许多的自定义属性,索性就不用代码动态添加了,哈哈,偷懒了!
有两种状态,一种是关注成功,一种是关注失败,这两个设定都是通过暴露方法之后在MainActivity中进行实现的。
下面来看代码:
//完成方法
public void setOnInnerFinish(String text) {
Message message = Message.obtain();
message.obj = text;
message.what = 1;
handler.sendMessage(message);
}
//失败完成方法
public void setOnInnerUnFinish(final String text) {
Message message = Message.obtain();
message.obj = text;
message.what = 0;
handler.sendMessage(message);
}
这里有个问题,就是之前在写代码的时候,progressBar的setVisivility(View.GONE)没有任何效果,之后,我才发现烦了低级错误。。。
应该在UI线程刷新控件:
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
progressBar.clearAnimation();
progressBar.setVisibility(View.GONE);
button.setTextColor(getResources().getColor(R.color.colorWhite));
button.setText(msg.obj.toString());
button.setBackgroundResource(R.drawable.unclickshape);
Toast.makeText(context, "关注失败!", Toast.LENGTH_SHORT).show();
break;
case 1:
progressBar.setVisibility(View.GONE);
button.setTextColor(getResources().getColor(R.color.colorBlack));
button.setText(msg.obj.toString());
button.setBackgroundResource(R.drawable.clickshape);
Toast.makeText(context, "关注成功!", Toast.LENGTH_SHORT).show();
break;
case 2:
//设定按钮颜色以及进度条可见性
progressBar.setVisibility(View.VISIBLE);
button.setText(msg.obj.toString());
break;
}
完整布局如下:
/**
* 自定义多种状态的按钮
* Created by Jiang on 2017-07-15.
*/
public class MyStateButton extends RelativeLayout {
private Context context;
private Button button;
private ProgressBar progressBar;
private ButtonClickListener buttonClickListener;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
progressBar.clearAnimation();
progressBar.setVisibility(View.GONE);
button.setTextColor(getResources().getColor(R.color.colorWhite));
button.setText(msg.obj.toString());
button.setBackgroundResource(R.drawable.unclickshape);
Toast.makeText(context, "关注失败!", Toast.LENGTH_SHORT).show();
break;
case 1:
progressBar.setVisibility(View.GONE);
button.setTextColor(getResources().getColor(R.color.colorBlack));
button.setText(msg.obj.toString());
button.setBackgroundResource(R.drawable.clickshape);
Toast.makeText(context, "关注成功!", Toast.LENGTH_SHORT).show();
break;
case 2:
//设定按钮颜色以及进度条可见性
progressBar.setVisibility(View.VISIBLE);
button.setText(msg.obj.toString());
break;
}
}
};
public interface ButtonClickListener {
void innerClick();
}
//点击监听
public void setOnInnerClickeListener(ButtonClickListener buttonClickListener) {
this.buttonClickListener = buttonClickListener;
}
//完成方法
public void setOnInnerFinish(String text) {
Message message = Message.obtain();
message.obj = text;
message.what = 1;
handler.sendMessage(message);
}
//失败完成方法
public void setOnInnerUnFinish(final String text) {
Message message = Message.obtain();
message.obj = text;
message.what = 0;
handler.sendMessage(message);
}
public MyStateButton(Context context) {
super(context);
this.context = context;
}
public MyStateButton(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public MyStateButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
}
/**
* 初始化布局
*/
private void initView() {
//获取外布局的宽高
int totalWidth = getMeasuredWidth();
int totalHeight = getMeasuredHeight();
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof Button) {
button = (Button) getChildAt(i);
//摆放子View,参数分别是子View矩形区域的左、上、右、下边
child.layout(0, 0, totalWidth, totalHeight);
}
if (getChildAt(i) instanceof ProgressBar) {
progressBar = (ProgressBar) getChildAt(i);
//摆放子View,参数分别是子View矩形区域的左、上、右、下边
child.layout(0, 0, totalWidth, totalHeight);
}
}
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if ("已关注".equals(button.getText().toString().trim())) {
return;
}
Message message = Message.obtain();
message.obj = "";
message.what = 2;
handler.sendMessage(message);
if (buttonClickListener != null) {
buttonClickListener.innerClick();
}
}
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);
for (int i = 0; i < getChildCount(); i++) {
View childView = getChildAt(i);
int a = childView.getMeasuredWidth();
int b = childView.getMeasuredHeight();
}
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// super.onLayout(changed, l, t, r, b);
initView();
}
}
public class MainActivity extends AppCompatActivity {
private MyStateButton myStateButton;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// myStateButton.setOnInnerUnFinish("关注");
myStateButton.setOnInnerFinish("已关注");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myStateButton = (MyStateButton) findViewById(R.id.mystatebar);
myStateButton.setOnInnerClickeListener(new MyStateButton.ButtonClickListener() {
@Override
public void innerClick() {
Message msg = Message.obtain();
handler.sendMessageDelayed(msg,2000);
}
});
}
}
这里有个小小的问题,在我的安卓4.4手机上可以正常运行,但是在安卓7.0的手机上运行,展示不出来进度条,第一次写自定义控件的开源项目,希望大家多多包涵啊!
终于解决了,参考了点击打开链接文章,在布局文件里面,给Button套了一层布局:
if (child instanceof RelativeLayout) {
button = (Button) ((RelativeLayout) child).getChildAt(0);
// button = (Button) getChildAt(i);
//摆放子View,参数分别是子View矩形区域的左、上、右、下边
child.layout(0, 0, totalWidth, totalHeight);
}
if (getChildAt(i) instanceof ProgressBar) {
progressBar = (ProgressBar) getChildAt(i);
//摆放子View,参数分别是子View矩形区域的左、上、右、下边
child.layout(0, 0, totalWidth, totalHeight);
}
}
源码地址:
MyStateButton