自定义view--自定义分类Tab菜单条,自定义垂直progressbar(类似温度计)
2016-07-18 16:45
417 查看
前不久做的一个项目用到了好多自定义的view,先写个博客记录一下其中两个,比较简单,就放到一个博客里写吧。
1,分类Tab菜单条
首先自定义属性:
<declare-styleable name="titleBar">
<attr name="first" format="string|reference"></attr>
<attr name="second" format="string|reference"></attr>
<attr name="third" format="string|reference"></attr>
<attr name="forth" format="string|reference"></attr>
</declare-styleable>
上代码:自定义TabarView
public class TabBarView extends RelativeLayout implements OnClickListener {
private Context mContext;
private TextView tab1;
private TextView tab2;
private TextView tab3;
private TextView tab4;
//tab的索引
public static final int CLICK_POSITION_FIRST = 0;
public static final int CLICK_POSITION_SECOND = 1;
public static final int CLICK_POSITION_THIRD = 2;
public static final int CLICK_POSITION_FORTH = 3;
private TabClickListener onTabClickListener;
public TabBarView(Context context) {
super(context);
mContext = context;
initView();
}
public TabBarView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initView();
TypedArray array = context.obtainStyledAttributes(attrs,
R.styleable.titleBar);
tab1.setText(array.getText(R.styleable.titleBar_first));
tab2.setText(array.getText(R.styleable.titleBar_second));
tab3.setText(array.getText(R.styleable.titleBar_third));
tab4.setText(array.getText(R.styleable.titleBar_forth));
array.recycle();
}
private void initView() {
LayoutInflater.from(mContext).inflate(R.layout.title_bar_layout, this);
tab1 = (TextView) findViewById(R.id.tv_tab1);
tab2 = (TextView) findViewById(R.id.tv_tab2);
tab3 = (TextView) findViewById(R.id.tv_tab3);
tab4 = (TextView) findViewById(R.id.tv_tab4);
tab1.setOnClickListener(this);
tab2.setOnClickListener(this);
tab3.setOnClickListener(this);
tab4.setOnClickListener(this);
}
//设置点击的tab
public void setClickPosition(int position) {
if (position == CLICK_POSITION_FIRST) {
tab1.performClick();
}
if (position == CLICK_POSITION_SECOND) {
tab2.performClick();
}
if (position == CLICK_POSITION_THIRD) {
tab3.performClick();
}
if (position == CLICK_POSITION_FORTH) {
tab4.performClick();
}
}
@Override
public void onClick(View v) {
v.setEnabled(false);
switch (v.getId()) {
case R.id.tv_tab1:
tab2.setEnabled(true);
tab3.setEnabled(true);
tab4.setEnabled(true);
if (onTabClickListener != null)
onTabClickListener.onFirstTabClick(v);
break;
case R.id.tv_tab2:
tab1.setEnabled(true);
tab3.setEnabled(true);
tab4.setEnabled(true);
if (onTabClickListener != null)
onTabClickListener.onSecondTabClick(v);
break;
case R.id.tv_tab3:
tab1.setEnabled(true);
tab2.setEnabled(true);
tab4.setEnabled(true);
if (onTabClickListener != null)
onTabClickListener.onThirdTabClick(v);
break;
case R.id.tv_tab4:
tab1.setEnabled(true);
tab2.setEnabled(true);
tab3.setEnabled(true);
if (onTabClickListener != null)
onTabClickListener.onForthTabClick(v);
break;
default:
break;
}
}
//设置监听
public void setOnTabClickListener(TabClickListener listener){
onTabClickListener=listener;
}
/**
* @author finn
* tab点击事件监听 接口
*/
public interface TabClickListener{
void onFirstTabClick(View v);
void onSecondTabClick(View v);
void onThirdTabClick(View v);
void onForthTabClick(View v);
}
}MainActivity中调用
public class MainActivity extends Activity implements TabClickListener {
private ImageView imageView;
private TabBarView barView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView=(ImageView) findViewById(R.id.imageview);
barView=(TabBarView) findViewById(R.id.custom_titlebar_view);
barView.setOnTabClickListener(this);
barView.setClickPosition(TabBarView.CLICK_POSITION_FIRST);
}
@Override
public void onFirstTabClick(View v) {
// TODO Auto-generated method stub
imageView.setBackgroundResource(R.drawable.image1);
}
@Override
public void onSecondTabClick(View v) {
// TODO Auto-generated method stub
imageView.setBackgroundResource(R.drawable.image2);
}
@Override
public void onThirdTabClick(View v) {
// TODO Auto-generated method stub
imageView.setBackgroundResource(R.drawable.image3);
}
@Override
public void onForthTabClick(View v) {
// TODO Auto-generated method stub
imageView.setBackgroundResource(R.drawable.image4);
}然后在MainActivity的布局中引用自定义view以及自定义的属性,注意要新增加一个新的的命名空间xmlns:custom="http://schemas.android.com/apk/res-auto"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" >
<TextView
android:id="@+id/tv_tab1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/index_tab_selecor"
android:gravity="center"
/>
<TextView
android:id="@+id/tv_tab2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_weight="1"
android:gravity="center"
android:background="@drawable/index_tab_selecor"
/>
<TextView
android:id="@+id/tv_tab3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_weight="1"
android:gravity="center"
android:background="@drawable/index_tab_selecor"
/>
<TextView
android:id="@+id/tv_tab4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_weight="1"
android:gravity="center"
and
4000
roid:background="@drawable/index_tab_selecor"
/>
</LinearLayout>
这里的点击效果selectort里可以放自定义的图片
第一个自定义view完毕,很简单,源码在此,点击下载。
2,自定义垂直progressbar(类似温度计)
项目中遇到要做成温度计形式的垂直进度条,根据数值变化进度条会上升和下降,很简单
上代码:
public class CustomDialogCheckMoisure extends Dialog{
private Context context;
private ImageView iv_exit;
private String moisure;
private ProgressBar progressBar1;
private int waterRate;
private TextView tv_moisure;
public CustomDialogCheckMoisure(Context context,String moisure) {
super(context,R.style.alert_dialog);
this.context=context;
this.moisure=moisure;
if(Double.parseDouble(moisure)>0 && Double.parseDouble(moisure)<1){
waterRate=1;
}else{
String s=String.valueOf(Math.round(Double.parseDouble(moisure)));
waterRate=Integer.parseInt(s);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.humidty_dialog_layout);
initView();
new MyAsyncTask().execute(0);
}
private void initView() {
tv_moisure=(TextView) findViewById(R.id.tv_moisure);
tv_moisure.setText(moisure);
iv_exit=(ImageView) findViewById(R.id.iv_exit);
progressBar1=(ProgressBar) findViewById(R.id.progressBar1);
iv_exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CustomDialogCheckMoisure.this.dismiss();
}
});
}
@Override
public void show() {
super.show();
}
//这里用AsyncTask做一下进度条上升的动画效果
private class MyAsyncTask extends AsyncTask<Integer, Integer, Integer> {
public MyAsyncTask() {
// TODO Auto-generated constructor stub
}
@Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
// arcProgressBar.setProgress(100);
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
Log.v("czm", "" + values[0]);
progressBar1.setProgress(values[0]);
}
@Override
protected Integer doInBackground(Integer... params) {
// TODO Auto-generated method stub
Integer timer = 0;
while (timer <= waterRate) {
try {
publishProgress(timer);
timer++;
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
}
}这里自定义了一个dialog来实现自定义弹出框,改变了他的风格,弹出的时候传入一些数据然后做了一些操作。
这个diaog的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/loading"
android:layout_width="@dimen/alert_width1"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/dialog_background"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp" >
<ImageView
android:id="@+id/iv_exit"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/exit"
android:layout_gravity="top|right"
/>
<FrameLayout
android:id="@+id/progress_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="9dp"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/progressBar1"
android:layout_width="60dp"
android:layout_height="180dp"
android:indeterminateOnly="false"
android:background="@drawable/thermometer_bg"
android:progressDrawable="@drawable/moisure_progressbar_bg" >
</ProgressBar>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="含水率:"
android:textColor="#575757"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_moisure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/normalcolorr"
android:layout_marginLeft="5dp"
android:textSize="19sp" />
</LinearLayout>
</LinearLayout>我们来看看这个自定义的progressbar的属性,其中 android: indeterminateOnly属性,指定其值为false,不显示原本默认的进度条 。然后我们设置它的背景android:background="@drawable/thermometer_bg",这是最下面一层的图片背景。最后我们来看怎么显示进度,这个属性android:progressDrawable="@drawable/moisure_progressbar_bg"
,moisure_progressbar_bg 文件如下:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/progress">
<clip
android:clipOrientation="vertical"
android:drawable="@drawable/thermometer_second_bg"
android:gravity="bottom" />
</item>
</layer-list>设置它的方向为垂直,设置他的第二层图片,设置它gravity属性,就大功告成了!
好了第二个自定义的view也完成了,这其中也查了好多资料,看过好多别人写的博客,其中难免有错误或者不足,有疑问的小伙伴可以留言交流。
源码在此,点击下载
1,分类Tab菜单条
首先自定义属性:
<declare-styleable name="titleBar">
<attr name="first" format="string|reference"></attr>
<attr name="second" format="string|reference"></attr>
<attr name="third" format="string|reference"></attr>
<attr name="forth" format="string|reference"></attr>
</declare-styleable>
上代码:自定义TabarView
public class TabBarView extends RelativeLayout implements OnClickListener {
private Context mContext;
private TextView tab1;
private TextView tab2;
private TextView tab3;
private TextView tab4;
//tab的索引
public static final int CLICK_POSITION_FIRST = 0;
public static final int CLICK_POSITION_SECOND = 1;
public static final int CLICK_POSITION_THIRD = 2;
public static final int CLICK_POSITION_FORTH = 3;
private TabClickListener onTabClickListener;
public TabBarView(Context context) {
super(context);
mContext = context;
initView();
}
public TabBarView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initView();
TypedArray array = context.obtainStyledAttributes(attrs,
R.styleable.titleBar);
tab1.setText(array.getText(R.styleable.titleBar_first));
tab2.setText(array.getText(R.styleable.titleBar_second));
tab3.setText(array.getText(R.styleable.titleBar_third));
tab4.setText(array.getText(R.styleable.titleBar_forth));
array.recycle();
}
private void initView() {
LayoutInflater.from(mContext).inflate(R.layout.title_bar_layout, this);
tab1 = (TextView) findViewById(R.id.tv_tab1);
tab2 = (TextView) findViewById(R.id.tv_tab2);
tab3 = (TextView) findViewById(R.id.tv_tab3);
tab4 = (TextView) findViewById(R.id.tv_tab4);
tab1.setOnClickListener(this);
tab2.setOnClickListener(this);
tab3.setOnClickListener(this);
tab4.setOnClickListener(this);
}
//设置点击的tab
public void setClickPosition(int position) {
if (position == CLICK_POSITION_FIRST) {
tab1.performClick();
}
if (position == CLICK_POSITION_SECOND) {
tab2.performClick();
}
if (position == CLICK_POSITION_THIRD) {
tab3.performClick();
}
if (position == CLICK_POSITION_FORTH) {
tab4.performClick();
}
}
@Override
public void onClick(View v) {
v.setEnabled(false);
switch (v.getId()) {
case R.id.tv_tab1:
tab2.setEnabled(true);
tab3.setEnabled(true);
tab4.setEnabled(true);
if (onTabClickListener != null)
onTabClickListener.onFirstTabClick(v);
break;
case R.id.tv_tab2:
tab1.setEnabled(true);
tab3.setEnabled(true);
tab4.setEnabled(true);
if (onTabClickListener != null)
onTabClickListener.onSecondTabClick(v);
break;
case R.id.tv_tab3:
tab1.setEnabled(true);
tab2.setEnabled(true);
tab4.setEnabled(true);
if (onTabClickListener != null)
onTabClickListener.onThirdTabClick(v);
break;
case R.id.tv_tab4:
tab1.setEnabled(true);
tab2.setEnabled(true);
tab3.setEnabled(true);
if (onTabClickListener != null)
onTabClickListener.onForthTabClick(v);
break;
default:
break;
}
}
//设置监听
public void setOnTabClickListener(TabClickListener listener){
onTabClickListener=listener;
}
/**
* @author finn
* tab点击事件监听 接口
*/
public interface TabClickListener{
void onFirstTabClick(View v);
void onSecondTabClick(View v);
void onThirdTabClick(View v);
void onForthTabClick(View v);
}
}MainActivity中调用
public class MainActivity extends Activity implements TabClickListener {
private ImageView imageView;
private TabBarView barView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView=(ImageView) findViewById(R.id.imageview);
barView=(TabBarView) findViewById(R.id.custom_titlebar_view);
barView.setOnTabClickListener(this);
barView.setClickPosition(TabBarView.CLICK_POSITION_FIRST);
}
@Override
public void onFirstTabClick(View v) {
// TODO Auto-generated method stub
imageView.setBackgroundResource(R.drawable.image1);
}
@Override
public void onSecondTabClick(View v) {
// TODO Auto-generated method stub
imageView.setBackgroundResource(R.drawable.image2);
}
@Override
public void onThirdTabClick(View v) {
// TODO Auto-generated method stub
imageView.setBackgroundResource(R.drawable.image3);
}
@Override
public void onForthTabClick(View v) {
// TODO Auto-generated method stub
imageView.setBackgroundResource(R.drawable.image4);
}然后在MainActivity的布局中引用自定义view以及自定义的属性,注意要新增加一个新的的命名空间xmlns:custom="http://schemas.android.com/apk/res-auto"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:custom="http://schemas.android.com/apk/res-auto" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <com.example.customtitlebar.TabBarView android:id="@+id/custom_titlebar_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" custom:first="第一个" custom:forth="第四个" custom:second="第二个" custom:third="第三个" > </com.example.customtitlebar.TabBarView> <ImageView android:id="@+id/imageview" android:layout_width="wrap_content" android:layout_height="300dp" android:scaleType="fitCenter" /> </LinearLayout>最后呢就是自定义view的布局文件,也很简单
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" >
<TextView
android:id="@+id/tv_tab1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/index_tab_selecor"
android:gravity="center"
/>
<TextView
android:id="@+id/tv_tab2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_weight="1"
android:gravity="center"
android:background="@drawable/index_tab_selecor"
/>
<TextView
android:id="@+id/tv_tab3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_weight="1"
android:gravity="center"
android:background="@drawable/index_tab_selecor"
/>
<TextView
android:id="@+id/tv_tab4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_weight="1"
android:gravity="center"
and
4000
roid:background="@drawable/index_tab_selecor"
/>
</LinearLayout>
这里的点击效果selectort里可以放自定义的图片
第一个自定义view完毕,很简单,源码在此,点击下载。
2,自定义垂直progressbar(类似温度计)
项目中遇到要做成温度计形式的垂直进度条,根据数值变化进度条会上升和下降,很简单
上代码:
public class CustomDialogCheckMoisure extends Dialog{
private Context context;
private ImageView iv_exit;
private String moisure;
private ProgressBar progressBar1;
private int waterRate;
private TextView tv_moisure;
public CustomDialogCheckMoisure(Context context,String moisure) {
super(context,R.style.alert_dialog);
this.context=context;
this.moisure=moisure;
if(Double.parseDouble(moisure)>0 && Double.parseDouble(moisure)<1){
waterRate=1;
}else{
String s=String.valueOf(Math.round(Double.parseDouble(moisure)));
waterRate=Integer.parseInt(s);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.humidty_dialog_layout);
initView();
new MyAsyncTask().execute(0);
}
private void initView() {
tv_moisure=(TextView) findViewById(R.id.tv_moisure);
tv_moisure.setText(moisure);
iv_exit=(ImageView) findViewById(R.id.iv_exit);
progressBar1=(ProgressBar) findViewById(R.id.progressBar1);
iv_exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CustomDialogCheckMoisure.this.dismiss();
}
});
}
@Override
public void show() {
super.show();
}
//这里用AsyncTask做一下进度条上升的动画效果
private class MyAsyncTask extends AsyncTask<Integer, Integer, Integer> {
public MyAsyncTask() {
// TODO Auto-generated constructor stub
}
@Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
// arcProgressBar.setProgress(100);
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
Log.v("czm", "" + values[0]);
progressBar1.setProgress(values[0]);
}
@Override
protected Integer doInBackground(Integer... params) {
// TODO Auto-generated method stub
Integer timer = 0;
while (timer <= waterRate) {
try {
publishProgress(timer);
timer++;
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
}
}这里自定义了一个dialog来实现自定义弹出框,改变了他的风格,弹出的时候传入一些数据然后做了一些操作。
这个diaog的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/loading"
android:layout_width="@dimen/alert_width1"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/dialog_background"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp" >
<ImageView
android:id="@+id/iv_exit"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/exit"
android:layout_gravity="top|right"
/>
<FrameLayout
android:id="@+id/progress_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="9dp"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/progressBar1"
android:layout_width="60dp"
android:layout_height="180dp"
android:indeterminateOnly="false"
android:background="@drawable/thermometer_bg"
android:progressDrawable="@drawable/moisure_progressbar_bg" >
</ProgressBar>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="含水率:"
android:textColor="#575757"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_moisure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/normalcolorr"
android:layout_marginLeft="5dp"
android:textSize="19sp" />
</LinearLayout>
</LinearLayout>我们来看看这个自定义的progressbar的属性,其中 android: indeterminateOnly属性,指定其值为false,不显示原本默认的进度条 。然后我们设置它的背景android:background="@drawable/thermometer_bg",这是最下面一层的图片背景。最后我们来看怎么显示进度,这个属性android:progressDrawable="@drawable/moisure_progressbar_bg"
,moisure_progressbar_bg 文件如下:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/progress">
<clip
android:clipOrientation="vertical"
android:drawable="@drawable/thermometer_second_bg"
android:gravity="bottom" />
</item>
</layer-list>设置它的方向为垂直,设置他的第二层图片,设置它gravity属性,就大功告成了!
好了第二个自定义的view也完成了,这其中也查了好多资料,看过好多别人写的博客,其中难免有错误或者不足,有疑问的小伙伴可以留言交流。
源码在此,点击下载
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories