首页 > 技术文章 > Android学习十二:自定义控件学习

supertonny 2015-06-09 23:59 原文

自定义控件:

1.定义控件的属性,atts.xml

2.代码实现自定义控件的控制

3.引用该控件

 

首先定义相关的属性

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="TopBar">
        <!-- title提示已经定义,那就直接引用 -->
        <attr name="title" />
        <attr name="titleTextSize" format="string" />
        <attr name="titleTextColor" format="reference|color" />
        <attr name="leftTextColor" format="reference|color" />
        <attr name="leftBgColor" format="reference|color" />
        <attr name="leftText" format="string" />
        <attr name="rightTextColor" format="color" />
        <attr name="rightBgColor" format="reference|color" />
        <attr name="rightText" format="string" />
    </declare-styleable>

</resources>

 

然后,设置控件布局

package org.tonny;

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 mLeftButton;
    private Button mRightButton;
    private TextView mTextView;

    //自定义控件布局的设置
    private LayoutParams mLeftParams;
    private LayoutParams mRightParams;
    private LayoutParams mCenterParams;

    //定义成员,与atts中的对应,对应mLeftButton
    private int mLeftTextColor;
    private Drawable mLeftBackground;
    private String mLeftText;

    //对应mRightButton
    private int mRightTextColor;
    private Drawable mRightBackground;
    private String mRightText;

    //对应mTextView
    private int mTitleTextSize;
    private int mTitleTextColor;
    private String mTitle;
    
    //定义接口,用于回调事件
    private onTopbarClickListener mLlistener;

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

        // 获取属性,将xml中值映射到ta中
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TopBar);

        mLeftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor, 0);
        mLeftBackground = ta.getDrawable(R.styleable.TopBar_leftBgColor);
        mLeftText = ta.getString(R.styleable.TopBar_leftText);

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

        mTitleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, 0);
        mTitle = ta.getString(R.styleable.TopBar_title);

        // 注意回收,这个很重要
        ta.recycle();

        // 设置相应控件的属性
        mLeftButton = new Button(context);
        mLeftButton.setTextColor(mLeftTextColor);
        mLeftButton.setBackgroundDrawable(mLeftBackground);
        mLeftButton.setText(mLeftText);
        
        //注意这个地方的使用
        mLeftButton.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                mLlistener.leftClick();

            }
        });

        mRightButton = new Button(context);
        mRightButton.setTextColor(mRightTextColor);
        mRightButton.setBackgroundDrawable(mRightBackground);
        mRightButton.setText(mRightText);
        mRightButton.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                mLlistener.rightClick();

            }
        });

        mTextView = new TextView(context);

        // 这个地方使用浮点数的形式会出错,不知道为啥
        mTextView.setTextSize(mTitleTextSize);
        mTextView.setTextColor(mTitleTextColor);
        mTextView.setText(mTitle);
        mTextView.setGravity(Gravity.CENTER);

        // 将控件添加到viewgroup中

        // 添加左按钮到布局中
        mLeftParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
        addView(mLeftButton, mLeftParams);

        // 添加右按钮到布局中
        mRightParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
        addView(mRightButton, mRightParams);

        // 添加标题到布局中
        mCenterParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        mCenterParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
        addView(mTextView, mCenterParams);
    }

    public void setOnTopbarClickListener(onTopbarClickListener listener)
    {
        mLlistener = listener;
    }
}

 

接口代码

package org.tonny;

//定义接口,用于回调
public interface onTopbarClickListener
{
    public void leftClick();

    public void rightClick();
}

 

其次,引用

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bar="http://schemas.android.com/apk/res/org.tonny"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <!-- 注意 xmlns:bar="http://schemas.android.com/apk/res/org.tonny"    命名空间的使用,bar是引入的控件的别名,可以自己定义因为需要引用自定义的leftBgColor,所以需要设置这个引用空间 -->

    <org.tonny.TopBar
        android:id="@+id/topBar"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        bar:leftBgColor="#F00FFF"
        bar:leftText="Back"
        bar:leftTextColor="#FFFFFF"
        bar:rightBgColor="#F00FFF"
        bar:rightText="More"
        bar:rightTextColor="#FFFFFF"
        bar:title="自定义控件测试"
        bar:titleTextColor="#00FFFF"
        bar:titleTextSize="40sp" >
    </org.tonny.TopBar>

</RelativeLayout>

 

最后,测试

package org.tonny;

import android.app.Activity;
import android.os.Bundle;
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);
        
        //获取topbar控件
        mTopbar = (TopBar) findViewById(R.id.topBar);
        
        //设置mTopbar的点击事件
        mTopbar.setOnTopbarClickListener(new onTopbarClickListener()
        {

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

            }

            @Override
            public void leftClick()
            {
                Toast.makeText(MainActivity.this, "back clicked", Toast.LENGTH_SHORT).show();

            }
        });
    }
}

 

推荐阅读