自定义View 标题栏

上一篇我们通过在布局文件中include的方法,引用标题栏进行复用。下面我们将标题栏封装为View,并可以实现在布局中设置属性,和在Java代码中通过各种方法设置。

首先还是上一篇中的标题栏布局 titlebar.xml:

<RelativeLayout             xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="44dp" 
    android:background="@color/bg_white">

    <TextView 
        android:id="@+id/titlebar_tv"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:maxWidth="224dp"
        style="@style/TextViewTitle"
        />
    <TextView 
        android:id="@+id/titlebar_tv_left"
        style="@style/TextViewTitleSide"
        />
    <TextView android:id="@+id/titlebar_tv_right"
        style="@style/TextViewTitleSide"
        android:layout_alignParentRight="true"/>
    <ImageView android:id="@+id/titlebar_iv_left"
        style="@style/ImageViewTitleSide"/>
    <ImageView android:id="@+id/titlebar_iv_right"
        style="@style/ImageViewTitleSide"
        android:layout_alignParentRight="true"/>
</RelativeLayout>

其中的自定义style:

    <style name="TextViewTitle">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:singleLine">true</item>
        <item name="android:textSize">@dimen/txt_title</item>
        <item name="android:textColor">@color/txt_black</item>
    </style>
    <style name="TextViewTitleSide">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">match_parent</item>
        <item name="android:gravity">center</item>
        <item name="android:visibility">gone</item>
        <item name="android:paddingLeft">16dp</item>
        <item name="android:paddingRight">16dp</item>
        <item name="android:textSize">@dimen/txt_subhead</item>
        <item name="android:textColor">@color/txt_black</item>
    </style>
    <style name="ImageViewTitleSide">
        <item name="android:layout_width">48dp</item>
        <item name="android:layout_height">match_parent</item>
        <item name="android:visibility">gone</item>
        <item name="android:padding">12dp</item>
    </style>

新建TitleBar.java,它就是我们今天的主角了,我们的自定义控件。继承自RelativeLayout,在构造方法中inflate布局,而且还要暴露一些方法,titlebar.xml:

public class TitleBar extends RelativeLayout{
    TextView tv;
    TextView tv_left;
    TextView tv_right;
    ImageView iv_left;
    ImageView iv_right;
    public TitleBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout. titlebar, this);

        tv = (TextView) findViewById(R.id.titlebar_tv);
        tv_left = (TextView) findViewById(R.id.titlebar_tv_left);
        tv_right = (TextView) findViewById(R.id.titlebar_tv_right);
        iv_left = (ImageView) findViewById(R.id.titlebar_iv_left);
        iv_right = (ImageView) findViewById(R.id.titlebar_iv_right);
        }
    public TitleBar setTitle(String str) {
        tv.setText(str);
        return this;
    }
    public TitleBar setTextLeft(String str) {
        tv_left.setVisibility(View.VISIBLE);
        tv_left.setText(str);
        return this;
    }
    public TitleBar setTextRight(String str) {
        tv_right.setVisibility(View.VISIBLE);
        tv_right.setText(str);
        return this;
    }
    public TitleBar setTextLeftGONE() {
        tv_right.setVisibility(View.GONE);
        return this;
    }
    public TitleBar setImageLeftRes(int Res) {
        setTextLeftGONE();
        iv_left.setVisibility(View.VISIBLE);
        iv_left.setImageResource(Res);
        return this;
    }
    public TitleBar setImageRightRes(int Res) {
        iv_right.setVisibility(View.VISIBLE);
        iv_right.setImageResource(Res);
        return this;
    }
    public void setListener(final TitleListenr listenr){
        if(tv_left.getVisibility() == View.VISIBLE) {
            tv_left.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    listenr.onLeftClickListener();
                }
            });
        }
        if(iv_left.getVisibility() == View.VISIBLE) {
            iv_left.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    listenr.onLeftClickListener();
                }
            });
        }
        if(tv_right.getVisibility() == View.VISIBLE) {
            iv_left.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    listenr.onRightClickListener();
                }
            });
        }
        if(iv_right.getVisibility() == View.VISIBLE) {
            iv_left.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    listenr.onRightClickListener();
                }
            });
        }
    }
    public interface TitleListenr{
        void onLeftClickListener();
        void onRightClickListener();
    }
}

我们自定义了TitleListenr接口,这样在一个方法中同时可以设置两个监听事件。 在布局文件中添加控件。这样我们完成了一期工程。 现在我们想在布局文件中也可以设置控件的属性。

新建attrs.xml,利用declare-styleable实现自定义控件属性。

<resources>
    <declare-styleable name="TitleBar">
        <attr name="titleText" format="string"/>
        <attr name="tv_left" format="string"/>
        <attr name="tv_right" format="string"/>
        <attr name="iv_left" format="reference"/>
        <attr name="iv_right" format="reference"/>
        <attr name="tv_left_visibility">
            <enum name="visible" value="0"/>
            <enum name="invisible" value="4"/>
            <enum name="gone" value="8"/>
        </attr>
        <attr name="tv_right_visibility">
            <enum name="visible" value="0"/>
            <enum name="invisible" value="4"/>
            <enum name="gone" value="8"/>
        </attr>
        <attr name="iv_left_visibility">
            <enum name="visible" value="0"/>
            <enum name="invisible" value="4"/>
            <enum name="gone" value="8"/>
        </attr>
        <attr name="iv_right_visibility">
            <enum name="visible" value="0"/>
            <enum name="invisible" value="4"/>
            <enum name="gone" value="8"/>
        </attr>
    </declare-styleable>
</resources>

完善TitleBar.java中的代码,使属性的设置能有些卵用:

    ...
    public TitleBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout. titlebar, this);

        tv = (TextView) findViewById(R.id.titlebar_tv);
        tv_left = (TextView) findViewById(R.id.titlebar_tv_left);
        tv_right = (TextView) findViewById(R.id.titlebar_tv_right);
        iv_left = (ImageView) findViewById(R.id.titlebar_iv_left);
        iv_right = (ImageView) findViewById(R.id.titlebar_iv_right);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TitleBar);
        String title = a.getString(R.styleable.TitleBar_titleText);
        String tv_leftText = a.getString(R.styleable.TitleBar_tv_left); 
        String tv_rightText = a.getString(R.styleable.TitleBar_tv_right); 
        Drawable iv_leftDraw = a.getDrawable(R.styleable.TitleBar_iv_left);
        Drawable iv_rightDraw = a.getDrawable(R.styleable.TitleBar_iv_right);
        int tv_left_visible = a.getInt(R.styleable.TitleBar_tv_left_visibility, 8);
        int tv_right_visible = a.getInt(R.styleable.TitleBar_tv_right_visibility, 8);
        int iv_left_visible = a.getInt(R.styleable.TitleBar_iv_left_visibility, 8);
        int iv_right_visible = a.getInt(R.styleable.TitleBar_iv_right_visibility, 8);
        tv.setText(title);
        tv_left.setText(tv_leftText);
        tv_right.setText(tv_rightText);
        iv_left.setImageDrawable(iv_leftDraw);
        iv_right.setImageDrawable(iv_rightDraw);
        tv_left.setVisibility(tv_left_visible);
        tv_right.setVisibility(tv_right_visible);
        iv_left.setVisibility(iv_left_visible);
        iv_right.setVisibility(iv_right_visible);
        a.recycle();
    }
    ...

接着在activtiy_second.xml布局文件中进行一些设置

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:my="http://schemas.android.com/apk/res/wang.titledemo"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <view.TitleBar
        android:id="@+id/titleBarId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        my:titleText = "haha" 
        my:tv_right = "右"
        my:tv_right_visibility = "visible"
        />

</LinearLayout>

这里注意要在开头进行引用,类似Java中的import。
在SecondActivity.class中进行设置,当然首先要findView:

public class SecondActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_second);

        TitleBar titleBar = (TitleBar) findViewById(R.id.titleBarId);
        titleBar.setTextLeft("后退").setListener(new TitleListenr() {
            @Override
            public void onRightClickListener() {
            }
            @Override
            public void onLeftClickListener() {
                finish();
            }
        });
    }
}

在代码中的设置会覆盖掉xml文件中的配置,和所有其他的View一样。当然在代码中,也可以用上一篇替代的Builder设计模式,方法完全一样。

end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值