自定义控件对于新手来说用画笔来做是不是觉得很难蛋疼呢?今天就给大家发福利了!我们不用画笔自定义进度条做一个山寨迅雷下载进度条。(其他某些控件也可)来,代码加注释
先上图:看看我们的效果:
点击下面的按钮:中间进度条正在下载
好了,先布局吧
<pre name="code" class="java"><?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" >
<!-- 这是迅雷下载条界面,包括两部分
1:ProgressBar 显示下载的进度
2:TextView 下载的进度,当然也可以说是下载的速度,看你想传什么参数决定
-->
<!--
重点1:把进度条设置为圆形和进度方向向上
重点2:捆绑Textview
-->
<ProgressBar
android:id="@+id/xuleibar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerInParent="true"
android:max="100"
<span style="white-space:pre"> </span><!-- 这个是我们等下自定义出来的文件,先不管 往下看 -->
android:progressDrawable="@drawable/newbar" />
<TextView
android:id="@+id/xuleitxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
重点来了,怎么设置进度条的属性呢?
我们想要改变系统控件的一些属性是不是通过在XML或者在代码中给控件设置你想要的属性呢?如果效果在复杂一点我们就会用到style或者anim了是不是?所以,我们可以通过修改ProgressBar的style来改变它的模样!那我们怎么去找到ProgressBar的style呢?
1:进入你的adt目录下,Ctrl+f 搜索 styles.xml 这时系统定义的所有style都在这了
2:Ctrl+f 搜索 styles.xml 再加一个关键字ProgressBar这时就定位到一个XML
3:先把它拖进Eclipse看看,在Eclipse Ctrl+f 搜索 ProgressBar
看到系统给我们定义的属性了吗?
现在重点来了,我们迅雷ProgressBar要修改什么属性呢?
1:两种颜色:一是蓝色,二是背景色白色
2:把方向改变,从水平改为垂直
3:形状修改为圆形
那到底是哪个呢?是 Widget.ProgressBar.Horizontal这个属性里面的
我们按着Ctrl 鼠标指向红色标注的地方单击进去------>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff9d9e9d"
android:centerColor="#ff5a5d5a"
android:centerY="0.75"
android:endColor="#ff747674"
android:angle="270"
/>
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#80ffd300"
android:centerColor="#80ffb600"
android:centerY="0.75"
android:endColor="#a0ffcb00"
android:angle="270"
/>
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="270"
/>
</shape>
</clip>
</item>
</layer-list>
这个就是ProgressBar的属性了。当然我们不可以直接在里面改。我们在res下新建一个drawable的file
创建一个newbar.xml 选择layer-list,因为要跟系统文件里的属性一致
把系统文件layer-list里面的item全部拷贝进去进行修改
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/background">
<shape>
<!--把进度条背景的四个角的半径设为80dp -->
<corners android:radius="80dip" />
<stroke
android:dashGap="0dp"
<!-- *******把进度条外面的边框设为1dp****** -->
android:width="1dp"
<!-- *******把进度条外面的边框颜色设为白色****** -->
android:color="@android:color/white" />
<gradient
<!-- *******把进度条的方向设为垂直****** -->
android:angle="90"
android:centerColor="#f0f3f5"
android:centerX="75"
android:endColor="#f0f3f5"
android:startColor="#f0f3f5" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip
android:clipOrientation="vertical"
android:gravity="bottom" >
<shape>
<corners android:radius="80dip" />
<stroke
android:dashGap="0dp"
android:width="1dp"
android:color="@android:color/white" />
<gradient
android:angle="90"
android:centerColor="#c27ba0"
android:centerX="75"
android:endColor="#c27ba0"
android:startColor="#c27ba0" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip
android:clipOrientation="vertical"
android:gravity="bottom" >
<shape>
<corners android:radius="80dip" />
<stroke
android:dashGap="0dp"
android:width="1dp"
android:color="@android:color/white" />
<gradient
android:angle="90"
<!--把进度条的进度的颜色设为蓝色 -->
android:centerColor="#3f82c3"
android:centerX="75"
android:endColor="#3f82c3"
android:startColor="#3f82c3" />
</shape>
</clip>
</item>
</layer-list>
重要的 地方已经写了注释,其他的不同自己对照,现在回到上面第一个布局文件,
android:progressDrawable="@drawable/newbar" 是不是就明白了呢?
还有就是,我的进度条宽高设置为了80dp,是为什么呢?因为我的圆角设置为了40dp
这样它们显示出来的就是圆了.....是两倍关系哦,你想要其他形状就自己决定吧
这样我们的进度条已经ok了。
现在来自定义控件---在class中绑定
package com.xuleibar.tool;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.gwl.xunleibar.R;
public class XunLeiBar extends LinearLayout{
private ProgressBar mPb;
private TextView mTv;
//重写第二个构造方法
public XunLeiBar(Context context, AttributeSet attrs) {
super(context, attrs);
//找到布局文件,找到id
LayoutInflater.from(context).inflate(R.layout.xunleibar_tool, this, true);
mPb = (ProgressBar) findViewById(R.id.xuleibar);
mTv = (TextView) findViewById(R.id.xuleitxt);
}
<span style="white-space:pre"> </span>//自定义<span style="font-family: Arial, Helvetica, sans-serif;">setProgress</span><span style="font-family: Arial, Helvetica, sans-serif;">方法,使得文本与进度条同步</span>
public void setProgress(int size) {
mPb.setProgress(size);
mTv.setText(size+"%");
}
<pre name="code" class="java"><span style="white-space:pre"> </span>//自定义<span style="font-family: Arial, Helvetica, sans-serif;">setTextColor</span><span style="font-family: Arial, Helvetica, sans-serif;">方法,改变字体颜色</span>
public void setTextColor(int color){mTv.setTextColor(color);}}
这样就做好了自定义控件
接下来就在主界面实现它们吧!------->
主界面的布局不做详解了,自己看
<RelativeLayout 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:background="#b9bed0"
tools:context=".MainActivity" >
<ImageButton
android:id="@+id/btn_main"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp"
android:background="@drawable/btn_main"
android:contentDescription="@string/hello_world"
android:text="@string/hello_world" />
<!-- 包名加类名引用控件 -->
<com.xuleibar.tool.XunLeiBar
android:id="@+id/xlbar_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="30dp" />
</RelativeLayout>
package com.gwl.xunleibar;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import com.xuleibar.tool.XunLeiBar;
public class MainActivity extends Activity {
XunLeiBar mXl;
ImageButton mbtn;
//实现线程间通信
@SuppressLint("HandlerLeak")
Handler mHandler = new Handler() {
@SuppressLint({ "ResourceAsColor", "InlinedApi" })
public void handleMessage(Message msg) {
//更新进度条的进度
mXl.setProgress(msg.arg1);
// if (msg.arg1 >= 50) {
// mXl.setTextColor(android.R.color.white);
// }else{
// mXl.setTextColor(android.R.color.holo_blue_light);
// }
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mXl = (XunLeiBar) findViewById(R.id.xlbar_main);
mbtn = (ImageButton) findViewById(R.id.btn_main);
//按钮的点击事件
mbtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//创建线程
new Thread(new Runnable() {
@Override
public void run() {
//每过0.1秒发一次数据,模拟下载
int i = 0;
while (i < 100) {
i = i + 2;
try {
Thread.sleep(100);
Message msg = mHandler.obtainMessage();
msg.arg1 = i;
msg.sendToTarget();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
});
}
}
我的按钮比较好看也是自定义过的。在此就不再说了。
程序跑起---------------------------->