自定义控件01---简单view的实现

对于每一个应用来说几乎都会有一个Topbar,并且基本都是类似的那么假如应用有好多个页面的话,就要写好多遍,可以在Topbar整合为一个控件来使用,针对于这个的学习,总结如下:

1 atts自定义属性的定义

res–values-atts.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="Topbar">
        <attr name="titleMiddle" format="string"/>
        <attr name="titleTextSize" format="dimension"/>
        <attr name="titleTextColor" format="color"/>
        <attr name="leftTextColor" format="color"/>
         <attr name="leftBackgroubd" format="reference|color"/>
        <attr name="leftText" format="string"/>
        <attr name="rightTextColor" format="color"/>
        <attr name="rightBackgroubd" format="reference|color"/>
        <attr name="rightText" format="string"/>

    </declare-styleable>

</resources>

2 自定义Topbar类继承RelativeLayout

package com.example.mytobbar;

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.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class Topbar extends RelativeLayout{

    //定义自定义的属性对应的控件
    private Button leftButton,rightButton;
    private TextView tvTextView;

    private int leftTextColor;
    private Drawable leftbackground;
    private String leftText;

    private int rightTextColor;
    private Drawable rightbackground;
    private String rightText;

    private float titleTextSize;
    private int titleTextColor;
    private String titleText;

    private LayoutParams leftParams,rightParams,titleParams; //用于把控件放到布局中


    //定义一个借口 用于点击事件方法的回调
    public interface TopbarOnClick{
        public void leftOnClick();
        public void rightOnClick();
        public void titleOnClick();
    }


    //接口的实例,作为类的成员变量
    private TopbarOnClick click;

    //对外暴露一个方法 把借口作为参数传入  就能回调到接口中的方法
    public void  setTopbarOnClick(TopbarOnClick click){
        this.click=click;
    }


    public Topbar(Context context, AttributeSet attrs) {
        super(context, attrs);

        //是控件和自定义的属性相连接
        /*
         * 1 建立映射,获取自定义的属性集合获取一个typedArray的数据结果,可以在typedArray中取出相应的值
         * 2 获取对应的值,建立映射 1 相当于map的key在atts的名字   2  默认的属性设置
         * 3 使用完回收 避免浪费资源 避免错误
         * */

        //获取自定义的属性集合
        TypedArray ad=context.obtainStyledAttributes(attrs, R.styleable.Topbar);

        //获取对应的值,建立映射        相当于map的key在atts的名字   0 默认的属性设置
        leftTextColor=ad.getColor(R.styleable.Topbar_leftTextColor, 0);
        leftbackground=ad.getDrawable(R.styleable.Topbar_leftBackgroubd);
        leftText=ad.getString(R.styleable.Topbar_leftText);

        rightTextColor=ad.getColor(R.styleable.Topbar_rightTextColor, 0);
        rightbackground=ad.getDrawable(R.styleable.Topbar_rightBackgroubd);
        rightText=ad.getString(R.styleable.Topbar_rightText);

        titleTextSize=ad.getDimension(R.styleable.Topbar_titleTextSize, 0);
        titleTextColor=ad.getColor(R.styleable.Topbar_titleTextColor,0);
        titleText=ad.getString(R.styleable.Topbar_titleMiddle);

        // 使用完回收 避免浪费资源 避免错误
        ad.recycle();


        //实例化控件
        leftButton=new Button(context);
        rightButton=new Button(context);
        tvTextView=new TextView(context);

        //将自定义的属性付给控件
        leftButton.setText(leftText);
        leftButton.setBackground(leftbackground);
        leftButton.setTextColor(leftTextColor);

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

        tvTextView.setText(titleText);
        tvTextView.setTextColor(titleTextColor);
        tvTextView.setTextSize(titleTextSize);
        tvTextView.setGravity(Gravity.CENTER);

        setBackgroundColor(0XFFF59563); //给view设置背景色

        //把定义的控件放到布局中

        leftParams=new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);//控件是包裹内容的
        leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE); //添加限制条件 居左  相对布局才有的属性 自定义控件用那上级谁的属性多最好就继承谁来自定义
        addView(leftButton, leftParams);

        //设置button的大小可以设置固定的值 就不会导致背景过大 像效果图一样了
        rightParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
        rightParams.setMargins(30, 0, 30, 0);
        addView(rightButton, rightParams);

        titleParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        titleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
        addView(tvTextView,titleParams);


        //添加点击事件
        leftButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                //点击事件调用类中接口的方法,便会调用此接口的实体的方法
                click.leftOnClick();

            }
        });
        rightButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                click.rightOnClick();
            }
        });

        tvTextView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                click.titleOnClick();

            }
        });
    }

}

3 布局文件中使用自定义的控件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    //自定义属性的命名空间com.example.mytobbar 为自定义控件类的包名
    xmlns:demoa="http://schemas.android.com/apk/res/com.example.mytobbar"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
      >

   <com.example.mytobbar.Topbar
       android:id="@+id/topbar"
       android:layout_width="fill_parent"
       android:layout_height="50dp"
       demoa:titleMiddle="中间标题"
       demoa:titleTextSize="15sp"
       demoa:titleTextColor="#FFFFFF"

       demoa:leftTextColor="#00FF00"
       demoa:rightTextColor="#FFFFFF"
       demoa:rightBackgroubd="@drawable/nothing_image"
       demoa:leftBackgroubd="@drawable/ic_launcher"
        demoa:leftText="左边"
       demoa:rightText="右边"
     >

   </com.example.mytobbar.Topbar>

</RelativeLayout>

4在activity中使用

package com.example.mytobbar;

import com.example.mytobbar.Topbar.TopbarOnClick;

import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import android.os.Build;

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);
        Topbar topbar = (Topbar) findViewById(R.id.topbar);
        topbar.setTopbarOnClick(new TopbarOnClick() {

            @Override
            public void titleOnClick() {
                Toast.makeText(getApplicationContext(), "title", 0).show();
            }

            @Override
            public void rightOnClick() {
                Toast.makeText(getApplicationContext(), "right", 0).show();

            }

            @Override
            public void leftOnClick() {
                Toast.makeText(getApplicationContext(), "left", 0).show();

            }
        });

    }



}

这里写图片描述

其中添加点击事件用到了接口的回调

添加接口回调的方法:

  • 1 在自定义的类中定义接口,并在接口中定义需要回调的方法
    -
//定义一个借口 用于点击事件方法的回调
    public interface TopbarOnClick{
        public void leftOnClick();
        public void rightOnClick();
        public void titleOnClick();
    }
 //接口的实例,作为类的成员变量
    private TopbarOnClick click;

  • 2 在自定义的类中写一个对外暴露的方法,把定义的接口作为方法的参数
  • `
//对外暴露一个方法 把借口作为参数传入  就能回调到接口中的方法
    public void  setTopbarOnClick(TopbarOnClick click){
        this.click=click;
    }
  • 3 在自定义的类中添加点击事件调用接口类的方法进行操作
  • ` //添加点击事件
    leftButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
    
            //点击事件调用类中接口的方法,便会调用此接口的实体的方法
            click.leftOnClick();
    
        }
    });`
    
  • 4 在需要调用自定义控件作为布局文件的activity中调用对外暴露的方法,这样当点击button时便会调用接口的方法,进而便会调用接口实体中实现的方法,就完成了回调
  • `topbar.setTopbarOnClick(new TopbarOnClick() {

        @Override
        public void titleOnClick() {
            Toast.makeText(getApplicationContext(), "title", 0).show();
        }
    
        @Override
        public void rightOnClick() {
            Toast.makeText(getApplicationContext(), "right", 0).show();
    
        }
    
        @Override
        public void leftOnClick() {
            Toast.makeText(getApplicationContext(), "left", 0).show();
    
        }
    });`
    
  • -

猜你喜欢

转载自blog.csdn.net/shuiermengqi/article/details/49000955