Android 自定义view模板并实现点击事件的回调

发布时间 - 2026-01-10 22:47:05    点击率:

Android 自定义view模板并实现点击事件的回调

主要的目的就是仿老版QQ的一个界面做一个模板。然后实现点击事件的回调。先看效果图:

步骤如下:

1.在res/values/目录下新建一个atts.xml文件

内容如下:

<resources>
  <declare-styleable name="topbar">
    <attr name="title" format="string"/>
    <attr name="titleBacgroud" format="reference|color"/>
    <attr name="titleSize" format="dimension"></attr>

    <attr name="leftBtnTitle" format="string"></attr>
    <attr name="leftBtnColor" format="color"></attr>
    <attr name="leftBtnSize" format="dimension"></attr>

    <attr name="rightBtnTitle" format="string"></attr>
    <attr name="rightBtnColor" format="color"></attr>
    <attr name="rightBtnSize" format="dimension"></attr>

  </declare-styleable>

attr.xml文件完成后,就是写一个TopBar.java文件来进行布局:

public class TopBar extends RelativeLayout{

  private Button leftBtn, rightBtn;
  private TextView tvTitle;

  private String title;
  private float titleSize ;
  private Drawable titleBackground;

  private String leftBtnTitle;
  private int leftBtnColor;
  private float leftBtnSize;

  private String rightBtnTitle;
  private int rightBtnColor;
  private float rightBtnSize;

  private LayoutParams leftBtnParams ,righBtnParams,titleParams;

  /**
   * 为TopBar添加回调点击事件,好处是不需要每次都修改TopBar中的点击事件,只需修改从外面传进来的Listener的点击事件
   * @param context
   * @param attrs
   */

  public interface topbarClickListener{
    void leftBtnClick();
    void rightBtnClick();
  }

  private topbarClickListener listener;

  public void setTopbarClickListener(topbarClickListener ls){
    this.listener = ls;
  }

  public TopBar(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub


    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.topbar);

    title = ta.getString(R.styleable.topbar_title);
    titleSize = ta.getDimension(R.styleable.topbar_titleSize, 0);
    titleBackground = ta.getDrawable(R.styleable.topbar_titleBacgroud);

    leftBtnTitle = ta.getString(R.styleable.topbar_leftBtnTitle);
    leftBtnColor = ta.getColor(R.styleable.topbar_leftBtnColor, 0);
    leftBtnSize = ta.getDimension(R.styleable.topbar_leftBtnSize, 0);

    rightBtnTitle = ta.getString(R.styleable.topbar_rightBtnTitle);
    rightBtnColor = ta.getColor(R.styleable.topbar_rightBtnColor, 0);
    rightBtnSize = ta.getDimension(R.styleable.topbar_rightBtnSize, 0);

    ta.recycle();//资源回收

    tvTitle = new TextView(context);
    leftBtn = new Button(context);
    rightBtn = new Button(context);

    tvTitle.setText(title);
    tvTitle.setTextSize(titleSize);
    tvTitle.setBackground(titleBackground);

    leftBtn.setText(leftBtnTitle);
    leftBtn.setTextColor(leftBtnColor);
    leftBtn.setTextSize(leftBtnSize);

    rightBtn.setText(rightBtnTitle);
    rightBtn.setTextColor(rightBtnColor);
    rightBtn.setTextSize(rightBtnSize);

    setBackgroundColor(Color.DKGRAY);//设置整个背景色

    /**
     * 将3个控件进行布局
     */
    //左边的按钮位于父布局的左边,通过addRule(RelativeLayout.ALIGN_PARENT_LEFT);来实现
    leftBtnParams = new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
        RelativeLayout.LayoutParams.WRAP_CONTENT);
    leftBtnParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
    leftBtnParams.setMargins(0, 18, 0, 0);
    addView(leftBtn, leftBtnParams);

    righBtnParams = new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
        RelativeLayout.LayoutParams.WRAP_CONTENT);
    righBtnParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    righBtnParams.setMargins(0, 18, 0, 0);
    addView(rightBtn, righBtnParams);
    //中间的TextView位于父布局的中间,addRule(RelativeLayout.CENTER_IN_PARENT);
    titleParams = new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
        RelativeLayout.LayoutParams.MATCH_PARENT);
    titleParams.addRule(RelativeLayout.CENTER_IN_PARENT);

    tvTitle.setGravity(Gravity.CENTER);

    addView(tvTitle, titleParams);


    leftBtn.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
        // TODO Auto-generated method stub
        listener.leftBtnClick();
      }
    });


    rightBtn.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
        // TODO Auto-generated method stub
        listener.rightBtnClick();
      }
    });

  }

  public void setTvTitle(String value){
    tvTitle.setText(value);
  }

}

TopBar是通过继承自RelativeLayout来实现的。

注意:由于我们的目的是自定义模板View,所以我们最好不要在TopBar.java中做如下操作:

leftBtn.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
        // TODO Auto-generated method stub
        //listener.leftBtnClick();//回调实现
        Toast.makeText(context, "LEFT BUTTOM CLICK", Toast.LENGTH_SHORT).show();
      }
    });


    rightBtn.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
        // TODO Auto-generated method stub
        //listener.rightBtnClick();//回调实现
        Toast.makeText(context, "RIGHT BUTTOM CLICK", Toast.LENGTH_SHORT).show();
      }
    });

如果这样做对于不同的点击事件都需要修改TopBar.java文件中的点击事件,失去了模板的意义。

主布局文件代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:custom="http://schemas.android.com/apk/res/com.example.viewpagerdemo"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >

  <com.example.viewpagerdemo.view.TopBar 
    android:id="@+id/topbar"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    custom:title="网易新闻"
    custom:titleBacgroud="#ff2255"
    custom:titleSize="30sp"
    custom:leftBtnTitle="BACK"
    custom:leftBtnColor="#ff4400"
    custom:leftBtnSize="24sp"
    custom:rightBtnTitle="MORE"
    custom:rightBtnColor="#ff4400"
    custom:rightBtnSize="24sp"
    ></com.example.viewpagerdemo.view.TopBar>

</LinearLayout>

上面的xmlns:custom=”http://schemas.android.com/apk/res/com.example.viewpagerdemo”是必须要添加的,res/ 后面是包名。作用相当于导入包名

MainActivity.java 文件如下:

public class TopBarActivity extends Activity{

  private TopBar mTopBar;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    setContentView(R.layout.topbar_layout);

    mTopBar = (TopBar) findViewById(R.id.topbar);

    /**
     * 利用回调实现TopBar的点击事件
     */
    mTopBar.setTopbarClickListener(new topbarClickListener() {

      @Override
      public void rightBtnClick() {
        // TODO Auto-generated method stub
        Toast.makeText(TopBarActivity.this, "RIGHT BUTTOM CLICK", Toast.LENGTH_SHORT).show();
      }

      @Override
      public void leftBtnClick() {
        // TODO Auto-generated method stub
        Toast.makeText(TopBarActivity.this, "LEFT BUTTOM CLICK", Toast.LENGTH_SHORT).show();
      }
    });

    //更改TopBar中显示的标题
    mTopBar.setTvTitle("凤凰网");

  }
}

这样可以在MainActivity中通过回调来实现点击事件。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# Android  # 自定义view模板并实现点击事件的回调  # view模板回调  # Android中父View和子view的点击事件处理问题探讨  # 实例详解Android解决按钮重复点击问题  # Android之有效防止按钮多次重复点击的方法(必看篇)  # Android 快速实现防止网络重复请求&按钮重复点击的方法  # Android 防止多次重复点击的三种方法的示例  # Android防止按钮重复点击示例代码  # Android优雅地处理按钮重复点击的几种方法  # Android中如何优雅的处理重复点击实例代码  # Android中AOP的应用实践之过滤重复点击  # Android开发教程之如何屏蔽View的重复点击  # 回调  # 来实现  # 自定义  # 不需要  # 只需  # 希望能  # 这样做  # 做一个  # 每次都  # 谢谢大家  # 先看  # 新建一个  # 网易新闻  # 背景色  # 中做  # 失去了  # 完成后  # 目录下  # 必须要  # 目的是 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中  网站制作免费,什么网站能看正片电影?  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复  JavaScript如何实现音频处理_Web Audio API如何工作?  如何快速搭建高效简练网站?  使用PHP下载CSS文件中的所有图片【几行代码即可实现】  魔毅自助建站系统:模板定制与SEO优化一键生成指南  ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法  php做exe能调用系统命令吗_执行cmd指令实现方式【详解】  为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】  JavaScript实现Fly Bird小游戏  Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程  专业商城网站制作公司有哪些,pi商城官网是哪个?  详解jQuery停止动画——stop()方法的使用  如何为不同团队 ID 动态生成多个非值班状态按钮  C#如何调用原生C++ COM对象详解  jQuery 常见小例汇总  javascript中数组(Array)对象和字符串(String)对象的常用方法总结  php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  浅析上传头像示例及其注意事项  laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法  宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法  微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】  如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?  Python文件异常处理策略_健壮性说明【指导】  使用C语言编写圣诞表白程序  深圳网站制作平台,深圳市做网站好的公司有哪些?  Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南  Laravel如何编写单元测试和功能测试?(PHPUnit示例)  Python进程池调度策略_任务分发说明【指导】  如何用PHP快速搭建CMS系统?  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  如何做网站制作流程,*游戏网站怎么搭建?  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  javascript日期怎么处理_如何格式化输出  MySQL查询结果复制到新表的方法(更新、插入)  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】  Chrome浏览器标签页分组怎么用_谷歌浏览器整理标签页技巧【效率】  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  Laravel如何配置任务调度?(Cron Job示例)  Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用  python中快速进行多个字符替换的方法小结  Laravel Seeder填充数据教程_Laravel模型工厂Factory使用  EditPlus中的正则表达式 实战(2)  android nfc常用标签读取总结  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置  EditPlus中的正则表达式实战(6)