You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Toolbar类触发EditText点击崩溃问题求助

点击自定义Toolbar中的EditText导致APP崩溃?问题排查+多类开发实用建议

问题背景

你之前一直用单一大型类开发,现在尝试为工具栏的EditText创建新类实现展开动画,但点击EditText时APP崩溃。目前MainActivity为空,后续计划添加WebView或其他组件。

你提供的代码

import android.support.v7.app.AppCompatActivity;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.EditText;
/**
 * Created by on 2018-01-07.
 */
public class Toolbar extends AppCompatActivity {
 EditText search;
 public void onEdit(){
 Animation scaleAnimation = new ScaleAnimation(0, -500, 1, 1);
 scaleAnimation.setDuration(750);
 scaleAnimation.setFillAfter(true);
 search.startAnimation(scaleAnimation);
 }
}

崩溃日志

01-07 05:09:41.007 943-1130/? E/OMX-VDEC-1080P: Does not handle dataspace request
01-07 05:09:41.007 943-1130/? E/OMXNodeInstance: getConfig(3af0069:qcom.decoder.avc, ??(0x7f000062)) ERROR: UnsupportedSetting(0x80001019)
01-07 05:09:41.009 943-2332/? E/OMX-VDEC-1080P: Does not handle dataspace request
01-07 05:09:41.009 943-2332/? E/OMXNodeInstance: getConfig(3af0069:qcom.decoder.avc, ??(0x7f000062)) ERROR: UnsupportedSetting(0x80001019)

问题排查与修复

你提供的崩溃日志是关于视频解码器的,和当前EditText动画崩溃无关,大概率是日志不全。从代码来看,有几个致命问题:

  1. 错误的类继承关系
    你的Toolbar类继承了AppCompatActivity,这完全不对!AppCompatActivity是页面容器,负责整个页面的生命周期,而Toolbar是一个UI组件,应该继承Android原生的Toolbar(或androidx.appcompat.widget.Toolbar),而不是Activity。把Activity当作UI组件用,必然会导致生命周期和初始化的混乱。

  2. 未初始化的View变量
    search这个EditText变量没有任何初始化代码(比如findViewById),直接调用search.startAnimation()会抛出NullPointerException,这是最常见的崩溃原因。

  3. ScaleAnimation参数错误
    ScaleAnimation(0, -500, 1, 1)的参数是缩放比例,不是像素值!比如0代表缩放到0(完全隐藏),1代表原大小,你写-500是完全不合理的,会导致动画逻辑异常。

修复后的代码示例

自定义Toolbar类(正确的继承方式)
import android.content.Context;
import android.util.AttributeSet;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.EditText;
import androidx.appcompat.widget.Toolbar;

public class CustomToolbar extends Toolbar {
    private EditText search;

    // 自定义View必须的构造方法
    public CustomToolbar(Context context) {
        super(context);
        init();
    }

    public CustomToolbar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomToolbar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    // 初始化子View
    private void init() {
        // 假设你的Toolbar布局里有id为search的EditText,这里通过findViewById初始化
        search = findViewById(R.id.search);
    }

    public void startSearchAnimation() {
        // 修正动画参数:x轴从0缩放到原大小,以View左侧为锚点,垂直方向保持原大小
        Animation scaleAnimation = new ScaleAnimation(
                0f, 1f,  // x轴起始/结束缩放比例
                1f, 1f,  // y轴起始/结束缩放比例
                Animation.RELATIVE_TO_SELF, 0f,  // x轴锚点:View自身左侧
                Animation.RELATIVE_TO_SELF, 0.5f // y轴锚点:View自身垂直中心
        );
        scaleAnimation.setDuration(750);
        scaleAnimation.setFillAfter(true);
        
        // 先判断search是否为空,避免空指针崩溃
        if (search != null) {
            search.startAnimation(scaleAnimation);
        }
    }
}
MainActivity中使用自定义Toolbar
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {
    private CustomToolbar customToolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); // 布局中要包含CustomToolbar

        // 初始化自定义Toolbar
        customToolbar = findViewById(R.id.custom_toolbar);
        
        // 给EditText设置点击事件,触发动画
        customToolbar.findViewById(R.id.search).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                customToolbar.startSearchAnimation();
            }
        });
    }
}

多类开发实用建议

从你之前只用单一大类的习惯来看,给你几个实用的开发原则,帮你理清代码结构:

  • 职责单一原则:每个类只做一件事。比如:

    • Activity/Fragment:负责页面的生命周期管理、业务逻辑协调、页面跳转。
    • 自定义View:专注于UI的展示、交互逻辑(比如你需要的动画效果)。
    • 工具类(Utils):封装通用功能(比如动画工具、字符串处理),方便多个地方复用。
    • 模型类(Model):封装数据结构(比如网络请求返回的内容)。
  • 避免错误继承:不要随便继承Activity/Fragment,只有当你需要创建一个新的页面时才用Activity;自定义UI组件要继承View或它的子类(比如Toolbar、LinearLayout)。

  • 强制初始化变量:所有View变量必须在使用前初始化(比如在Activity的onCreate、自定义View的init方法中调用findViewById),避免NullPointerException。

  • 学会看崩溃日志:你提供的日志和当前崩溃无关,下次要找Logcat中“Error”级别下的堆栈跟踪信息,里面会明确显示崩溃的类、方法和原因(比如NullPointerException会告诉你哪个变量为空)。

内容的提问来源于stack exchange,提问作者EquiWare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:39:35