android组合控件Titlebar的定制

poseiden 8年前

来自: http://blog.csdn.net/ydxlt/article/details/50805822

前言:我相信”天生我才必有用”这句话,每个人都有他的作用,也许他的作用相对其他人来不是很明显,也许他的作用也就是取悦别人,但是请不要忘记,可以通过不断努力来发挥自己的作用,使自己的价值得到提升。

在平时的android开发中你是否遇到一个问题,那就是每次都要自己写一个布局,或者是引入一个布局但每次都要为了给布局中的控件初始化。对于这个问题,谷歌官方推出了ActionBar,以及随后的取代ActionBar的ToolBar来使我们的开发更加简单,如:使用ToolBar+DrawLayout就非常容易实现推酷app的那种菜单效果。这样的一个控件的出现极大地减少了程序员的负担,使得android开发越来越简单,相信以后将会有更多类似的好的控件的出现来简化我们app的开发,呵呵,满期待的~。

这篇文章将介绍一个自己组合的控件Titlebar来简化我们的开发,这个组合控件的实现是个体力活(无技术含量),所以先看一下要实现的效果,如果觉得闭着眼睛就能写出来的,可以直接跳到本篇文章结尾为我辛勤的劳动点个赞,哈哈。

效果图:

实现这个组合控件需要我们自定义属性,写一个类继承ViewGroup并在构造方法中用代码添加子View。所以,下面先自定义我们的属性。

1. 自定义属性

通过观察上面的效果图,我们发现我们共需要以下11个属性:

  1. leftButtonText
  2. leftButtonTextColor
  3. leftButtonTextSize
  4. leftButtonImage:左侧按钮的图片
  5. titleText
  6. titleColor
  7. titleSize
  8. rightButtonText
  9. rightButtonTextColor
  10. rightButtonTextSize
  11. rightButtonImage:右侧按钮的图片

各个属性的意思根据名称就知道是什么意思,所以,我们就在资源文件attrs.xml来定义我们的属性:

<declare-styleable name="Titlebar">      <attr name="leftButtonText" format="string|reference"></attr>      <attr name="leftButtonTextColor" format="color|reference"></attr>      <attr name="leftButtonTextSize" format="dimension|reference"></attr>      <attr name="leftButtonImage" format="color|reference"></attr>        <attr name="titleText" format="string|reference"></attr>      <attr name="titleColor" format="color|reference"></attr>      <attr name="titleSize" format="dimension|reference"></attr>        <attr name="rightButtonText" format="string|reference"></attr>      <attr name="rightButtonTextColor" format="color|reference"></attr>      <attr name="rightButtonTextSize" format="dimension|reference"></attr>      <attr name="rightButtonImage" format="color|reference"></attr>    </declare-styleable>

注意:

  1. 我们可以attrs.xml的 <resources> 节点下面直接定义我们的属性而不必在 <declare-styleable> 节点下面定义或引用,然后在布局文件中直接使用,但这种做法不推荐,因为将一些属性添加到一个属性集 <declare-styleable> 中便于管理和使用。
  2. 如果自定义属性和系统属性重名的时候,如果我们要定义属性的类型和系统定义的一样,那么我们可以直接在 <declare-styleable> 节点中引用系统的属性,即添加一个 <attr> 节点但不要format属性;

2. 继承ViewGroup,完成控件的组合

观察我们要实现的效果,发现使用ViewGroup的子类RelativeLayout可以很好和方便地完成。所以,新建一个类继承RelativeLayout,重写三个构造方法,在构造方法中先获取布局中自定义属性的值。

private void init(Context context,AttributeSet attrs) {      TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Titlebar);      mLeftButtonText = typedArray.getString(R.styleable.Titlebar_leftButtonText);      mLeftButtonTextColor = typedArray.getColor(R.styleable.Titlebar_leftButtonTextColor, Color.GRAY);      mLeftButtonSize = typedArray.getDimension(R.styleable.Titlebar_leftButtonTextSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));      mLeftButtonImage = typedArray.getDrawable(R.styleable.Titlebar_leftButtonImage);        mTitleButtonText = typedArray.getString(R.styleable.Titlebar_titleText);      mTitleButtonTextColor = typedArray.getColor(R.styleable.Titlebar_titleColor, Color.GRAY);      mTitleButtonSize = typedArray.getDimension(R.styleable.Titlebar_titleSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));        mRightButtonText = typedArray.getString(R.styleable.Titlebar_rightButtonText);      mRightButtonTextColor = typedArray.getColor(R.styleable.Titlebar_rightButtonTextColor, Color.GRAY);      mRightButtonSize = typedArray.getDimension(R.styleable.Titlebar_rightButtonTextSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));      mRightButtonImage = typedArray.getDrawable(R.styleable.Titlebar_rightButtonImage);        typedArray.recycle();  }

这里使用完TypedArray这个资源后要记得回收资源,就像使用完数据库后要记得关闭连接和使用完IO流要记得关闭一样。

获取到了自定义属性的值,那么,我们还需要通过代码构建左侧按钮,中间标题,右侧按钮这三个控件:

private void initView(Context context) {      if(mLeftButtonImage == null & mLeftButtonText != null){          // 当用户没有设置左侧按钮图片并设置了左侧的按钮文本属性时--添加左侧文本按钮          mLeftTextView = new TextView(context);          mLeftTextView.setText(mLeftButtonText);          mLeftTextView.setTextColor(mLeftButtonTextColor);          mLeftTextView.setTextSize(mLeftButtonSize);          RelativeLayout.LayoutParams leftParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);          leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);          leftParams.addRule(RelativeLayout.CENTER_VERTICAL);          addView(mLeftTextView, leftParams);      }else if(mLeftButtonImage != null){          // 添加左侧图片按钮          RelativeLayout.LayoutParams leftParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);          leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);          leftParams.addRule(RelativeLayout.CENTER_VERTICAL);          mLeftButton = new ImageView(context);          mLeftButton.setImageDrawable(mLeftButtonImage);          addView(mLeftButton, leftParams);      }        if(mTitleButtonText!=null){          // 添加中间标题          TextView titleTextView = new TextView(context);          titleTextView.setText(mTitleButtonText);          titleTextView.setTextColor(mTitleButtonTextColor);          titleTextView.setTextSize(mTitleButtonSize);          RelativeLayout.LayoutParams titleTextViewParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);          titleTextViewParams.addRule(RelativeLayout.CENTER_IN_PARENT);          addView(titleTextView,titleTextViewParams);      }        if(mRightButtonImage == null & mRightButtonText != null){          // 当用户没有设置右侧按钮图片并设置了左侧的按钮文本属性时--添加右侧文本按钮          mRightTextView = new TextView(context);          mRightTextView.setText(mRightButtonText);          mRightTextView.setTextColor(mRightButtonTextColor);          mRightTextView.setTextSize(mRightButtonSize);          RelativeLayout.LayoutParams rightParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);          rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);          rightParams.addRule(RelativeLayout.CENTER_VERTICAL);          addView(mRightTextView,rightParams);      }else if(mRightButtonImage != null){          // 添加右侧图片按钮          RelativeLayout.LayoutParams rightParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);          rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);          rightParams.addRule(RelativeLayout.CENTER_VERTICAL);          mRightButton = new ImageView(context);          mRightButton.setImageDrawable(mRightButtonImage);          addView(mRightButton, rightParams);      }  }

说明:由于左侧和右侧的按钮既可以使用文字也可以使用图片,所以,这里我使用了两个控件代表这两种情况,当用户设置了左侧按钮图片后就不会添加左侧按钮文本。

接下来我们还需要为左侧和右侧按钮添加事件监听,所以,我们先定义一个接口:

/** * 在button点击事件接口 */  public interface OnButtonClickListener{      void onLeftClick();      void onRightClick();  }

设置按钮监听:

/** * 设置点击事件 * @param onButtonClickListener */  public void setOnButtonClickListener(final OnButtonClickListener onButtonClickListener) {      if(onButtonClickListener !=null){          if(mLeftTextView != null){              mLeftTextView.setOnClickListener(new OnClickListener() {                  @Override                  public void onClick(View v) {                      onButtonClickListener.onLeftClick();                  }              });          }          if(mLeftButton != null){              mLeftButton.setOnClickListener(new OnClickListener() {                  @Override                  public void onClick(View v) {                      onButtonClickListener.onLeftClick();                  }              });          }          if(mRightTextView != null){              mRightTextView.setOnClickListener(new OnClickListener() {                  @Override                  public void onClick(View v) {                      onButtonClickListener.onRightClick();                  }              });          }          if(mRightButton != null){              mRightButton.setOnClickListener(new OnClickListener() {                  @Override                  public void onClick(View v) {                      onButtonClickListener.onRightClick();                  }              });          }      }  }

布局中使用我们的组合控件:

include_titlebar.xml

<?xml version="1.0" encoding="utf-8"?>  <com.lt.titlebar.Titlebar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:lt="http://schemas.android.com/apk/res-auto" android:id="@+id/titlebar" android:layout_width="match_parent" android:layout_height="60dp" lt:leftButtonText="返回" lt:leftButtonTextColor="@android:color/white" lt:leftButtonTextSize="8sp" lt:titleText="标题" lt:titleColor="@android:color/white" lt:titleSize="8sp" lt:rightButtonText="完成" lt:rightButtonTextColor="@android:color/white" lt:rightButtonTextSize="8sp" android:background="#ea8010" android:padding="10sp" >    </com.lt.titlebar.Titlebar>

注意:

  • 命名空间的引入;
  • 使用我们自定义的属性可以使用4种情况的组合:

    1. 左侧为文本按钮,右侧为文本按钮;
    2. 左侧为文本按钮,右侧为图片按钮;
    3. 左侧为图片按钮,右侧为文本按钮;
    4. 左侧为图片按钮,右侧为图片按钮。
  • 在需要上面类似的标题栏的时候,直接在布局中include引入这个布局文件即可,然后在activity或fragment或其他使用这个控件的地方在初始化这个控件并设置接口监听即可。

在activity中初始化并设置接口监听:

Titlebar titlebar = (Titlebar) findViewById(R.id.titlebar);  titlebar.setOnButtonClickListener(new Titlebar.OnButtonClickListener() {      @Override      public void onLeftClick() {          Toast.makeText(MainActivity.this,"左侧按钮被点击了",0).show();      }        @Override      public void onRightClick() {          Toast.makeText(MainActivity.this,"右侧按钮被点击了",0).show();      }  });

就是个体力活,锻炼使用代码创建并布局控件的能力,没什么可总结的~

demo下载: http://download.csdn.net/detail/ydxlt/9453262