Android自定义复合控件

       在Android中,复合控件是非常常见的,下面以创建一个标题栏为例,讲解创建自定义复合控件的过程。

       以下图为例:我们要创建一个标题栏,这个标题栏是由左边的Button、右边的Button以及中间的TextView复合而成的,而我们希望能够直接在这个自定义标题栏设置里面的Button和TextView的属性信息。

       具体实现过程如下:

1、首先在res资源目录的values目录新建一个attrs.xml的属性定义文件,并在该文件中定义相应的属性。代码如下:

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

       这里定义了标题文字的内容、大小、颜色,左边按钮的文字内容、大小、颜色以及按钮的背景,右边按钮的文字内容、大小、颜色以及按钮的背景,值得一提的是,这里的背景属性既可以是颜色属性,也可以是引用属性,如引用一张图片,故这里使用了“|”来分隔不同的属性——“reference|color”。
2、自定义的ComplexView代码如下:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class ComplexView extends LinearLayout {
    private String titleText;//标题文字
    private float titleTextSize;//标题文字大小
    private int titleTextColor;//标题文字颜色

    private String leftText;//左边按钮文字
    private float leftTextSize;//左边按钮文字大小
    private int leftTextColor;//左边按钮文字颜色
    private Drawable leftBackground;//左边按钮背景

    private String rightText;//右边按钮文字
    private float rightTextSize;//右边按钮文字大小
    private int rightTextColor;//右边按钮文字颜色
    private Drawable rightBackground;//右边按钮背景

    private Button leftBtn;
    private TextView titleTv;
    private Button rightBtn;

    public ComplexView(Context context) {
        super(context);
    }

    public ComplexView(Context context, AttributeSet attrs) {
        super(context, attrs);
        parseAttributes(context.obtainStyledAttributes(attrs, R.styleable.TopBar));
        View view = LayoutInflater.from(context).inflate(R.layout.complex_view, this);
        leftBtn = (Button) view.findViewById(R.id.left_btn);
        rightBtn = (Button) view.findViewById(R.id.right_btn);
        titleTv = (TextView) view.findViewById(R.id.title_tv);
        //设置标题属性
        titleTv.setText(titleText);
        titleTv.setTextSize(titleTextSize);
        titleTv.setTextColor(titleTextColor);
        //设置左边按钮属性
        leftBtn.setText(leftText);
        leftBtn.setTextSize(leftTextSize);
        leftBtn.setTextColor(leftTextColor);
        leftBtn.setBackgroundDrawable(leftBackground);
        //设置右边按钮属性
        rightBtn.setText(rightText);
        rightBtn.setTextSize(rightTextSize);
        rightBtn.setTextColor(rightTextColor);
        rightBtn.setBackgroundDrawable(rightBackground);
        //左右按钮点击事件
        leftBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                onTopBarClickListener.leftClick();
            }
        });
        rightBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                onTopBarClickListener.rightClick();
            }
        });
    }

    //获取自定义属性集
    private void parseAttributes(TypedArray ta) {
        titleText = ta.getString(R.styleable.TopBar_titleText);
        titleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize, 25);
        titleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, 0);

        leftText = ta.getString(R.styleable.TopBar_leftText);
        leftTextSize = ta.getDimension(R.styleable.TopBar_leftTextSize, 16);
        leftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor, 0);
        leftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground);

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

        ta.recycle();
    }

    //为左右按钮设置点击事件,使用接口回调方法
    public interface onTopBarClickListener {
        void leftClick();

        void rightClick();
    }

    onTopBarClickListener onTopBarClickListener = null;

    public void setOnTopBarClickListener(onTopBarClickListener onTopBarClickListener) {
        this.onTopBarClickListener = onTopBarClickListener;
    }
}

    其中complex_view布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:id="@+id/left_btn"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dp" />

    <TextView
        android:id="@+id/title_tv"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center" />

    <Button
        android:id="@+id/right_btn"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dp" />
</LinearLayout>

3、在activity_main中引入ComplexView,为了引用自定义控件的属性,需要在activity_main布局文件中加入下面一句:

xmlns:app="http://schemas.android.com/apk/res-auto"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="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:orientation="vertical"
    tools:context=".MainActivity">

    <com.exam.myapplication.ComplexView
        android:id="@+id/top_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#008577"
        app:leftBackground="@drawable/btn_shape"
        app:leftText="返回"
        app:leftTextColor="#ffffff"
        app:leftTextSize="8sp"
        app:rightBackground="@drawable/btn_shape"
        app:rightText="更多"
        app:rightTextColor="#ffffff"
        app:rightTextSize="8sp"
        app:titleText="标题"
        app:titleTextColor="#ffffff"
        app:titleTextSize="10sp" />

</LinearLayout>

       上面的btn_shape其实是按钮的背景,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="3dp"/>
    <solid android:color="#00574B"/>
</shape>

4、我在自定义的ComplexView中还为左右按钮增加了点击事件,这里使用了接口回调方法,可以在MainActivity中实现具体的逻辑。代码如下:

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends Activity {
    ComplexView topBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        topBar = (ComplexView) findViewById(R.id.top_bar);
        topBar.setOnTopBarClickListener(new ComplexView.onTopBarClickListener() {
            @Override
            public void leftClick() {
                Toast.makeText(MainActivity.this, "返回", Toast.LENGTH_SHORT).show();
            }

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

      创建自定义复合控件的整个流程到此介绍完毕。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于 Android 自定义进度条控件的实现,我可以为您提供一些思路和示例代码。 首先,我们需要继承自 View 或者 ProgressBar,然后在 onDraw 方法中实现自己的绘制逻辑。具体来说,需要绘制背景、进度条和文本等内容。 示例代码如下: ```java public class CustomProgressBar extends ProgressBar { private Paint mPaint; private String mText; private Rect mRect; public CustomProgressBar(Context context) { super(context); init(); } public CustomProgressBar(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CustomProgressBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mRect = new Rect(); } @Override protected synchronized void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制背景 mPaint.setColor(Color.GRAY); mPaint.setStyle(Paint.Style.FILL); canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint); // 绘制进度条 mPaint.setColor(Color.BLUE); mPaint.setStyle(Paint.Style.FILL); float progress = getProgress() * 1.0f / getMax(); canvas.drawRect(0, 0, getWidth() * progress, getHeight(), mPaint); // 绘制文本 mPaint.setColor(Color.WHITE); mPaint.setTextSize(24); mText = getProgress() + "%"; mPaint.getTextBounds(mText, 0, mText.length(), mRect); float x = getWidth() / 2f - mRect.centerX(); float y = getHeight() / 2f - mRect.centerY(); canvas.drawText(mText, x, y, mPaint); } } ``` 这个自定义控件实现了一个简单的水平进度条,包括了背景、进度条和文本三个部分。当然,您可以根据自己的需求进行更改和扩展。 希望这个示例代码能够帮助到您,如果您还有其他问题,欢迎继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值