您的位置:首页 > 移动开发 > Android开发

自定义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"
<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也完成了,这其中也查了好多资料,看过好多别人写的博客,其中难免有错误或者不足,有疑问的小伙伴可以留言交流。

源码在此,点击下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息