安卓界面篇(一) 自定义一个topbar

步骤一: 先在values 里 新建一个attrs.xml 来设置我们的属性值:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TopBar" >
        <attr name="title" format="string"/>
        <attr name="titleTextSize" format="dimension"/>
        <attr name="titleTextColor" format="color"/>
        <attr name="leftText" format="string"/>
        <attr name="leftBackground" format="reference|color"/>
        <attr name="leftTextColor" format="color"/>
        <attr name="rightText" format="string"/>
        <attr name="rightBackground" format="reference|color"/>
        <attr name="rightTextColor" format="color"/>

    </declare-styleable>

</resources>

步骤二: 新建Topbar类继承自RelaiveLayout :

/**
 * Created by Ace on 2016/2/3.
 */
public class Topbar extends RelativeLayout {

    //声明我们需要的控件
    private Button leftButton,rightButton;
    private TextView tv_title;

    private int leftTextColor;
    private String leftText;
    private Drawable leftBackground;

    private int rightTextColor;
    private String rightText;
    private Drawable rightBackground;

    private String title;
    private int titleTextColor;
    private float titleTextSize;

    //4 定义布局属性
    private LayoutParams leftParams , rightParams,titleParams;

    public Topbar(Context context, AttributeSet attrs) {
        super(context, attrs);
        //1 通过 context.obtainStyledAttributes 得到 TypedArray对象 并拿到属性值
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TopBar);
        leftText = ta.getString(R.styleable.TopBar_leftText);
        leftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor, 0);
        leftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground);

        rightText = ta.getString(R.styleable.TopBar_rightText);
        rightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor, 0);
        rightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground);

        title = ta.getString(R.styleable.TopBar_title);
        titleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, 0);
        titleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize, 0);
        //记得回收下 防止出现一些内存问题
        ta.recycle();

        // 2 new出控件
        leftButton = new Button(context);
        rightButton = new Button(context);
        tv_title = new TextView(context);

        //3 把自定义的属性赋给控件

        leftButton.setTextColor(leftTextColor);
        leftButton.setBackground(leftBackground);
        leftButton.setText(leftText);

        rightButton.setTextColor(rightTextColor);
        rightButton.setBackground(rightBackground);
        rightButton.setText(rightText);

        tv_title.setTextColor(titleTextColor);
        tv_title.setTextSize(titleTextSize);
        tv_title.setText(title);
        tv_title.setGravity(Gravity.CENTER);

        setBackgroundColor(0xFFF59563);


        // 5 new出LayoutParams 设置宽高
        leftParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
        // 6 设置规则 可以看出LayoutParams布局参数就是把你的控件以什么样的方式显示在组合控件
        leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        //7 添加到布局中(控件,布局参数)
        addView(leftButton ,leftParams);
        rightParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
        rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        addView(rightButton, rightParams);
        titleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.MATCH_PARENT);
        titleParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        addView(tv_title,titleParams);

        //8 TopBar的静态部分已经完毕了 到这一步就很明白了 我们采用的组合方式,用系统以及有的控件组合在一起,组成一个新的控件,这个思路是否可以延伸到其他地方呢?思考下

    }

}

步骤三: 再Activity_main.xml中设置我们的自定义Topbar  重点我用红色和黄色标出,系统 xmlns(xml name space)的是:android 那么我们自己定义当然要有个个性的名字 我就写ace了, 再看后面res-auto ,这部分是控件属性资源地址.用AS的小伙伴

用res-auto就可以了 eslipse的小伙伴要写完整的地址 xmlns:XXXXXX="http://schemas.android.com/apk/res/包路径"

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ace="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="zb.com.topbardemo.MainActivity">


<zb.com.topbardemo.Topbar
    android:id="@+id/topbar"
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    ace:leftTextColor = "#FFFFFF"
    ace:leftText ="后退"
    ace:leftBackground = "#4e32b4"
    ace:rightTextColor = "#FFFFFF"
    ace:rightText ="设置"
    ace:rightBackground = "#4e32b4"
    ace:title = "我是ACE"
    ace:titleTextColor = "#e20f0f"
    ace:titleTextSize = "15sp"
    >

</zb.com.topbardemo.Topbar>


</RelativeLayout>

静态部分完成现在写Topbar的点击事件 在Topbar类里写 :

        leftButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context,"Ace Left",Toast.LENGTH_LONG).show();
            }
        });

        rightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context,"Ace Right",Toast.LENGTH_LONG).show();
            }
        });

这样是可以 但是却把按钮的点击事件写死了,我们要根据不同情况调用不同的点击事件就无法实现

.要解决这个问题那么要用到接口回调,系统也是如此来做得.         OnclickListener是一个接口 那么我们也新建一个接口topbarClickListener,添加两个方法(左Button的点击和右Button的点击)

package zb.com.topbardemo;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by Ace on 2016/2/3.
 */

  //定义一个topbarClickListener
    private topbarClickListener mListner;

    //定义一个接口 两个方法
    public interface topbarClickListener{
        public void leftClick();
        public void rightClick();
    }
    //暴露一个方法用来设置点击事件 并映射用户传进来的listner
    public void setTopbarClickListner(topbarClickListener listner){
       mListner = listner;
    }
.
.
.
.
.
.中间的代码省略跟前面一样不用变动
.
.
.
.
.       leftButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListner.leftClick();
            }
        });

        rightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListner.rightClick();
            }
        });


    }


}

这样 按钮的点击按钮要做什么完全取决于用户来设置

 

我们用我们自己的方法来设置点击事件

MainActivity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Topbar topbar =(Topbar)findViewById(R.id.topbar);
        topbar.setTopbarClickListner(new Topbar.topbarClickListener() {
            @Override
            public void leftClick() {
                Toast.makeText(MainActivity.this,"Ace left",Toast.LENGTH_LONG).show();
            }

            @Override
            public void rightClick() {
                Toast.makeText(MainActivity.this,"Ace right",Toast.LENGTH_LONG).show();

            }
        });


    }

}

我的AS出了点问题 暂时没有截图 抱歉~~~


原文地址:https://www.cnblogs.com/AceIsSunshineRain/p/5179676.html