android 组合方式自定义控件

实现了《android 群英传》的TopBar的小实例。效果图如下:

记录下来,方便下次查看。主要的原理是将2个Button和一个TextView组合在一个RelativeLayout之中。

代码如下。首先定义自定义属性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="leftTextColor" format="color" />
        <attr name="leftBackground" format="reference|color" />
        <attr name="leftText" format="string" />
        <attr name="rightTextColor" format="color" />
        <attr name="rightBackground" format="reference|color" />
        <attr name="rightText" format="string" />
    </declare-styleable>
</resources>

然后是自定一个一个TopBar,在之中组合Button和TextView,动态地设置属性值和布局。下面是自定义的按钮点击事件的接口。

package com.example.androidviewlearn;

public interface TopBarClickListener {

    void leftClick();
    void rightClick();

}

package com.example.androidviewlearn;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Trace;
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 {
    // 获取自定义的类型数组s
    private TypedArray ta;
    private int mLeftTextColor;
    private Drawable mLeftBackground;
    private String mLeftText;

    private int mRightTextColor;
    private Drawable mRightBackground;
    private String mRightText;

    private int mTitleTextSize;
    private int mTitleTextColor;
    private String mTtile;

    private Button mLeftButton;
    private Button mRightButton;
    private TextView mTitleView;

    private LayoutParams mLeftLayoutParams;
    private LayoutParams mRightLayoutParams;
    private LayoutParams mTitleLayoutParams;

    private TopBarClickListener mBarClickListener;

    //三个构造函数,一般采用这些写法。
    public TopBar(Context context) {
        this(context, null);
        // TODO Auto-generated constructor stub
    }
    public TopBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        // TODO Auto-generated constructor stub
    }
    @SuppressLint("NewApi")
    public TopBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub

        //获取布局中设置的自定义属性
        getStyleValue(context, attrs);
        //初始化控件,并且把属性值设置进去
        initView(context);
        //设置各个控件的布局
        setLayout();

    }

    /**
     * 设置自定义空间的布局属性
     */
    private void setLayout() {
        mLeftLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        mLeftLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
        addView(mLeftButton, mLeftLayoutParams);

        mRightLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        mRightLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
        addView(mRightButton, mRightLayoutParams);

        mTitleLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        mTitleLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
        addView(mTitleView, mTitleLayoutParams);
    }

    @SuppressLint("NewApi")
    /**
     * 初始化控件,并且给空间赋予属性和事件
     * @param context
     */
    private void initView(Context context) {
        mLeftButton = new Button(context);
        mRightButton = new Button(context);
        mTitleView = new TextView(context);

        mLeftButton.setTextColor(mLeftTextColor);
        mLeftButton.setText(mLeftText);
        mLeftButton.setBackground(mLeftBackground);
        mLeftButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View paramView) {
                // TODO Auto-generated method stub
                mBarClickListener.leftClick();
            }
        });

        mRightButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View paramView) {
                // TODO Auto-generated method stub
                mBarClickListener.rightClick();
            }
        });

        mRightButton.setTextColor(mRightTextColor);
        mRightButton.setText(mRightText);
        mRightButton.setBackground(mRightBackground);

        mTitleView.setText(mTtile);
        mTitleView.setTextColor(mTitleTextColor);
        mTitleView.setTextSize(mTitleTextSize);
        mTitleView.setGravity(Gravity.CENTER);
    }

    /**
     * 获取自定义空间上的style
     * @param context
     * @param attrs
     */
    private void getStyleValue(Context context, AttributeSet attrs) {
        ta = context.obtainStyledAttributes(attrs, R.styleable.TopBar);
        mLeftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor, 0);
        mLeftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground);
        mLeftText = ta.getString(R.styleable.TopBar_leftText);

        mRightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor, 0);
        mRightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground);
        mRightText = ta.getString(R.styleable.TopBar_rightText);

        mTitleTextSize = ta.getDimensionPixelSize(R.styleable.TopBar_titleTextSize, 10);
        mTitleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, 0);
        mTtile = ta.getString(R.styleable.TopBar_title);

        ta.recycle();
    }

    public TopBarClickListener getmBarClickListener() {
        return mBarClickListener;
    }

    public void setBarClickListener(TopBarClickListener mBarClickListener) {
        this.mBarClickListener = mBarClickListener;
    }

    /**
     * id=1标识→_→,id-0标识左边
     *
     * @param id
     * @param flag
     */
    public void setButtonVisable(int id, boolean flag) {
        if (flag) {
            if (id == 0) {
                mLeftButton.setVisibility(View.VISIBLE);
            } else {
                mRightButton.setVisibility(View.VISIBLE);
            }
        } else {
            if (id == 0) {
                mLeftButton.setVisibility(View.GONE);
            } else {
                mRightButton.setVisibility(View.GONE);
            }
        }

    }

}

之后定义一个layout,activity_main.xml,把放入自定义布局和设置参数。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.androidviewlearn.MainActivity" >

    <com.example.androidviewlearn.TopBar
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:custom="http://schemas.android.com/apk/res-auto"
        android:id="@+id/topBar"
        android:layout_width="match_parent"
        android:layout_height="40dp"

           custom:leftBackground="#98F5FF"
           custom:leftText="Back"
           custom:leftTextColor="#FFFAFA"

           custom:rightBackground="#98F5FF"
           custom:rightText="More"
           custom:rightTextColor="#FFFAFA"

           custom:title="Fuck Day"
           custom:titleTextColor="#123412"
           custom:titleTextSize="16sp"

         >

    </com.example.androidviewlearn.TopBar>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</LinearLayout>

特别注意这一行,xmlns:custom="http://schemas.android.com/apk/res-auto"。custom就表示了设置属性时候的前缀:custom:rightBackground

最后的就是Activity的实现了。

package com.example.androidviewlearn;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends Activity {
    private TopBar mTopBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTopBar = (TopBar) findViewById(R.id.topBar);
        mTopBar.setBarClickListener(new TopBarClickListener() {
            @Override
            public void rightClick() {
                // TODO Auto-generated method stub
                Toast.makeText(getApplicationContext(), "right fuck button", Toast.LENGTH_LONG).show();
            }
            @Override
            public void leftClick() {
                // TODO Auto-generated method stub
                Toast.makeText(getApplicationContext(), "left fuck button", Toast.LENGTH_LONG).show();
            }
        });
    }
}

时间: 2024-08-07 04:14:37

android 组合方式自定义控件的相关文章

Android开发技巧——自定义控件之自定义属性

Android开发技巧--自定义控件之自定义属性 掌握自定义控件是很重要的,因为通过自定义控件,能够:解决UI问题,优化布局性能,简化布局代码. 上一篇讲了如何通过xml把几个控件组织起来,并继承某个ViewGroup子类,把它们封装起来使用.这是我们接触到的最简单的一种自定制控件了.但许多时候,我们还需要在布局文件中使用它们的时候,能通过属性传入一些值,来影响最终的显示结果. 我们在做项目中经常会遇到的一个情况:一张图片加一个文本的组合.比如充值账户成功之后显示的一个界面,上面是一个表示成功的

荐 android 如何打包自定义控件(转)

荐 android 如何打包自定义控件(转) 目录[-] 方式一:将项目打包成jar包 方式二:项目作为一个library 设计自定义的控件对android开发人员来说,是家常便饭了,但是多次做项目的经验证明了一个道理,自定义的控件,可以在其他项目中,多次使用,所以接下来我们来介绍2种常用的打包方式,并讨论他们的利于病. 我们可以假设想要自定义一个改变文字显示的button(纯属假设,这样简单的功能其实也用不着自定义) 首先写好布局文件mybutton.xml 1 2 3 4 5 6 7 8 9

3、用继承和组合方式定制控件

定制控件的方式 ? 继承其它控件类(EditText.Button) ? 组合方式.当前控件类从容器类继承,并将若干个控件添加到当前的容器中. ? 绘制控件,也就是控件类从View继承,并在onDraw方法中从零绘制 控件.例如,TextView.  带标签的文本编辑框(不带命名空间) 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http:

android post方式上传文件(模拟表单格式数据提交)

表单提交内容为: POST /upload.php?zp_id=ab46ca6d703e3a1580c1c9b8b3a8fb39 HTTP/1.1Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/v

Android 存储文件方式之一---SharedPreferences 内容提供者,以xml 的方式进行数据 存储。是一种轻量级的文件数据存储

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 //UI界面的布局 文件<br><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"

六 APPIUM Android 定位方式

文本转自:http://www.cnblogs.com/sundalian/p/5629500.html APPIUM Android 定位方式 1.定位元素应用元素 1.1通过id定位元素 Android里面定位的id一般为resrouce-id: 代码可以这样写: WebElement element = driver.findElement(By.id("com.tencent.mm:id/do")); 或者: driver.findElementById("com.t

android dom方式创建xml

http://blog.csdn.net/nxh_love/article/details/7085174 在android dom 解析xml方式文章中,简单介绍了dom解析xml的应用.今天在原文章的基础上,说一下android中dom创建xml的应用. 首先:创建的文件会放在/data/data/cn.com.xxx(当前包名)/files下面. 创建生成的xml文件如下所示: [html] view plaincopy <?xml version="1.0" encodi

Canvas 图形组合方式

/** * 图形组合 */ function initDemo5() { var canvas = document.getElementById("demo5"); if (!canvas) return; var context = canvas.getContext("2d"); var oprtns = [ "source-atop", // 新图形覆盖原有图形,新图形未重叠部分透明 "source-in", // 新

用继承和组合方式定制控件

1. 定制控件的方式 2. 带标签的文本编辑框(不带命名空间) 3. 带图标的文本框(带命名空间) 4. 控件属性验证 1. 定制控件的方式 <1>继承其他控件类 Ctrl + 左键 --->EditText <2>组合方式. 当前控件类从容器类继承, 并将若干个控件添加到当前容器中 <3>绘制控件. 也就是控件类从View继承, 并在onDraw方法中从零开始绘制控件, 例如TextView 2. 带标签的文本编辑框(不带命名空间)