自定义控件实战-Android UI模板设计(文末小彩蛋)

原创 2016年08月29日 15:19:12

先简单说一下实现方向:



接下来我们一步步实现方向:

1.设计所需属性:

在value目录下新建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="leftBackground" format="reference|color"/>
        <attr name="leftText" format="string"/>
        <attr name="leftTextColor" format="color"/>

        <attr name="rightBackground" format="reference|color"/>
        <attr name="rightText" format="string"/>
        <attr name="rightTextColor" format="color"/>

    </declare-styleable>
</resources>


2.实现我们的View:

新建类继承RelativeLayout,重写构造方法,并在构造方法里进行映射,对应的属性赋值:

package com.quan.car.topbar;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * Created by 权兴权意 on 2016/8/29.
 */
public class TopBar extends RelativeLayout{

    private Button leftButton,rightButton;
    private TextView middleTitle;

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

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

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

    private LayoutParams leftParams,rightParams,titleParams;

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public TopBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        //自定义属性值映射
        TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.TopBar);

        //键值对,取值
        leftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor,0);
        leftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground);
        leftText = ta.getString(R.styleable.TopBar_leftText);
        rightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor,0);
        rightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground);
        rightText = ta.getString(R.styleable.TopBar_rightText);
        titleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize,0);
        titleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor,0);
        title = ta.getString(R.styleable.TopBar_title);

        ta.recycle();//回收,节约资源,避免错误;

        leftButton = new Button(context);
        rightButton = new Button(context);
        middleTitle = new TextView(context);

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

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

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

        setBackgroundColor(0xFFF59563);

        leftParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
        leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);
        addView(leftButton,leftParams);

        rightParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
        rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);
        addView(rightButton,rightParams);

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

3.引用View并模块化开发定义接口设置回调事件,

引用自定义控件:

定义命名空间:

    xmlns:custom="http://schemas.android.com/apk/res-auto"
引用控件并设置属性:

    <com.quan.car.topbar.TopBar
        android:id="@+id/topbar_tb_main"
        android:layout_height="40dp"
        android:layout_width="match_parent"
        custom:leftText="Back"
        custom:leftTextColor="#FFFFFF"
        custom:rightText="More"
        custom:rightTextColor="#FFFFFF"
        custom:title="自定义标题"
        custom:titleTextColor="#123412"
        custom:titleTextSize="10sp"
        ></com.quan.car.topbar.TopBar>

接口相关:

在TopBar.java中进行定义:

    private topbarClickListener listener;

    //定义接口
    public interface topbarClickListener{
        public void leftClick();
        public void rightClick();
    }

    //暴露方法
    public void setOnTopBarClickListener(topbarClickListener listener){
        this.listener = listener;
    }

leftButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                //Toast.makeText(context,"Left.",Toast.LENGTH_SHORT).show();
                listener.leftClick();
            }
        });
```
        rightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                //Toast.makeText(context,"Right.",Toast.LENGTH_SHORT).show();
                listener.rightClick();
            }
        });

在MainActivity.java中重写方法,进行注册:

        topBar.setOnTopBarClickListener(new TopBar.topbarClickListener() {
            @Override
            public void leftClick() {
                Toast.makeText(MainActivity.this,"Left.",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void rightClick() {
                Toast.makeText(MainActivity.this,"Right.",Toast.LENGTH_SHORT).show();
            }
        });


核心源代码:

Java:

package com.quan.car.topbar;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
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;

/**
 * Created by 权兴权意 on 2016/8/29.
 */
public class TopBar extends RelativeLayout{

    private Button leftButton,rightButton;
    private TextView middleTitle;

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

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

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

    private LayoutParams leftParams,rightParams,titleParams;

    private topbarClickListener listener;

    //定义接口
    public interface topbarClickListener{
        public void leftClick();
        public void rightClick();
    }

    //暴露方法
    public void setOnTopBarClickListener(topbarClickListener listener){
        this.listener = listener;
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public TopBar(final Context context, AttributeSet attrs) {
        super(context, attrs);
        //自定义属性值映射
        TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.TopBar);

        //键值对,取值
        leftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor,0);
        leftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground);
        leftText = ta.getString(R.styleable.TopBar_leftText);
        rightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor,0);
        rightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground);
        rightText = ta.getString(R.styleable.TopBar_rightText);
        titleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize,0);
        titleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor,0);
        title = ta.getString(R.styleable.TopBar_title);

        ta.recycle();//回收,节约资源,避免错误;

        leftButton = new Button(context);
        rightButton = new Button(context);
        middleTitle = new TextView(context);

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

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

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

        setBackgroundColor(0xFFF59563);

        leftParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
        leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);
        addView(leftButton,leftParams);

        rightParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
        rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);
        addView(rightButton,rightParams);

        titleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
        titleParams.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE);
        addView(middleTitle,titleParams);

        leftButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                //Toast.makeText(context,"Left.",Toast.LENGTH_SHORT).show();
                listener.leftClick();
            }
        });

        rightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                //Toast.makeText(context,"Right.",Toast.LENGTH_SHORT).show();
                listener.rightClick();
            }
        });
    }

    public void setLeftIsVisiable(boolean flag){
        if(flag){
            leftButton.setVisibility(View.VISIBLE);
        }else{
            leftButton.setVisibility(View.INVISIBLE);
        }
    }
}

xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.quan.car.topbar.MainActivity">

    <com.quan.car.topbar.TopBar
        android:id="@+id/topbar_tb_main"
        android:layout_height="40dp"
        android:layout_width="match_parent"
        custom:leftText="Back"
        custom:leftTextColor="#FFFFFF"
        custom:rightText="More"
        custom:rightTextColor="#FFFFFF"
        custom:title="自定义标题"
        custom:titleTextColor="#123412"
        custom:titleTextSize="10sp"
        ></com.quan.car.topbar.TopBar>

</RelativeLayout>

文末小彩蛋:

窗口切换键:alt+左/右

代码折叠/展开:ctrl+“+”/“-”

查找对应括号:ctrl+“[” / “]”

Surround With:ctrl+alt+t






Android UI 之一步步教你自定义控件(自定义属性、合理设计onMeasure、合理设计onDraw等)

Android开发做到了一定程度,多少都会用到自定义控件,一方面是更加灵活,另一方面在大数据量的情况下自定义控件的效率比写布局文件更高。 一个相对完善的自定义控件在布局文件中和java代码中都应能灵活...
  • carrey1989
  • carrey1989
  • 2013年09月17日 10:58
  • 21804

Android UI 模板

简单学习了Android UI 模板,自定义的UI模板,在自己设计的app中可以进行有效的代码复用。在这里做个流程整理,之后再添加漂亮的效果: 首先加个在线阅读Android 源码的链接 :http:...
  • NOMALJAVAEST
  • NOMALJAVAEST
  • 2016年03月07日 23:04
  • 415

APP开发实战149-Android Studio模板的定制使用

模板的定制使用 在用Android Studio的向导新建项目时,在如下界面显示许多AndroidStudio内置的Activity模板: 或在工程中选择新建Activity时,也可以选择内置的Ac...
  • xjbclz
  • xjbclz
  • 2017年01月07日 21:26
  • 2169

【UI学习】Android github开源项目,酷炫自定义控件(View)汇总

近期整理的比较酷炫并且我们会经常用到的custom view,也有一些不是custom view,但是也是android UI相关的,实现了酷炫UI效果的开源库,总结的项目最后维护时间一般不会超过6个...
  • hudan2714
  • hudan2714
  • 2016年09月04日 23:23
  • 3052

自定义控件(支持模板)

自定义控件(支持模板) 再说一下,这部分内容最好的教材就是我一开始推荐的那个视频材料。如果还有没有下的那就赶快去下~~指不定哪天微软的网站被攻击,倒闭了,就没的下了。不过话说回来,如果微软都倒闭了,那...
  • CrackLibby
  • CrackLibby
  • 2015年08月21日 15:20
  • 439

Python程序员都知道的5个彩蛋

程序员在大众眼中是一群智商高、情商低,少言寡语的人,这种由来已久的刻板印象源自于大众缺乏对程序员的真正了解,其实程序员和其它行业一样是个多元化的职业,也不乏幽默、高情商、口吐莲花的人。 看看...
  • zV3e189oS5c0tSknrBCL
  • zV3e189oS5c0tSknrBCL
  • 2017年09月24日 00:00
  • 618

安卓的UI设计规范及分辨率尺寸规范

Android的设计规范及分辨率尺寸 一:设计规范(以720*1280px为准): 注:所有的规范时基于320ppi的,要做其他分辨率的设计图,只需要把720*1280px对应的像素值换成 DP;...
  • weixin_37730482
  • weixin_37730482
  • 2017年09月25日 14:46
  • 885

1min了解Dialog(文末小彩蛋)

AlertDialog 可以在当前的界面弹出一个对话框,这个对话框是置顶于所有界面元素之上的,能够屏蔽掉其他控件的交互能力,因此一般AlertDialog 都是用于提示一些非常重要的内容或者警告信息。...
  • hxqneuq2012
  • hxqneuq2012
  • 2016年09月12日 20:07
  • 185

Android UI高级之自定义控件

Android UI高级之自定义控件 ----仿360加速器
  • qq_25034451
  • qq_25034451
  • 2016年05月20日 17:41
  • 744

关于android4.0.4中彩蛋的实现

情况: 在android4.0.4的系统设置-关于手机-Android版本,连续快速点击几下,就会出现一个机器人,长按住机器人不放,机器人会一直变大,然后出现一堆机器从屏幕上飞过 ...
  • victoryckl
  • victoryckl
  • 2012年11月15日 07:30
  • 2471
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自定义控件实战-Android UI模板设计(文末小彩蛋)
举报原因:
原因补充:

(最多只允许输入30个字)