【问题标题】:Removing a view from within its own view class从其自己的视图类中删除视图
【发布时间】:2015-03-07 04:35:15
【问题描述】:

这是我创建的视图类。

public class WorkoutView extends LinearLayout implements View.OnClickListener {


    public Spinner spinnerDifficulty, spinnerTime, spinnerMuscleGroup, spinnerSets, spinnerReps;
    public EditText etWorkoutName;
    public Button btnRemoveWorkout;

    String workoutName, muscleGroup, sets, reps;
    LayoutInflater inflater;
    Context mContext;
    ButtonPressInterface buttonPressCallback;

    public WorkoutView(Context context) {
        super(context);
        Log.e("WORKOUTVIEW", "1");
        mContext = context;

    }

    public WorkoutView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        Log.e("WORKOUTVIEW", "2");
    }

    public WorkoutView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        Log.e("WORKOUTVIEW", "3");
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        init();
    }

    public interface ButtonPressInterface {
        void buttonWasPressed();

    }

    public void init() {
        spinnerDifficulty = (Spinner) findViewById(R.id.spinnerDifficulty);
        spinnerReps = (Spinner) findViewById(R.id.spinnerReps);
        spinnerSets = (Spinner) findViewById(R.id.spinnerSets);
        spinnerMuscleGroup = (Spinner) findViewById(R.id.spinnerWorkoutGroup);
        spinnerTime = (Spinner) findViewById(R.id.spinnerTime);
        etWorkoutName = (EditText) findViewById(R.id.etWorkoutName);
        btnRemoveWorkout = (Button) findViewById(R.id.btnRemoveWorkout);
        btnRemoveWorkout.setOnClickListener(this);

        buttonPressCallback = (ButtonPressInterface) getContext();
    }

    public String getReps() {
        reps = spinnerReps.getSelectedItem().toString();
        return reps;
    }

    public String getWorkoutName() {
        workoutName = etWorkoutName.getText().toString().trim();
        return workoutName;
    }

    public String getMuscleGroup() {
        muscleGroup = spinnerMuscleGroup.getSelectedItem().toString();
        return muscleGroup;
    }

    public String getSets() {
        sets = spinnerSets.getSelectedItem().toString();
        return sets;
    }

    public SingleWorkout getAll() {
        //to be designed
        return null;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btnRemoveWorkout:
                buttonPressCallback.buttonWasPressed();
                Log.e("DID THIS WORK?", "BUTTON PRESSED");
                break;
        }

    }
}

如何在按下 btnRemoveWorkout 时移除此视图?有没有办法实现接口?这个视图被正确添加,所有其他方法都可以正常工作。

这是我在尝试以编程方式添加视图时收到的错误,这在我尝试实现回调到 Activity 的接口之前是可能的。

03-06 23:30:30.352    6986-6986/com.modup.app E/WORKOUTVIEW﹕ 2
03-06 23:30:30.372    6986-6986/com.modup.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.modup.app, PID: 6986
    java.lang.ClassCastException: com.modup.view.WorkoutView cannot be cast to com.modup.view.WorkoutView$ButtonPressInterface
            at com.modup.view.WorkoutView.init(WorkoutView.java:70)
            at com.modup.view.WorkoutView.onFinishInflate(WorkoutView.java:52)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:763)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
            at com.modup.fragment.CreateFragment.onClick(CreateFragment.java:197)
            at android.view.View.performClick(View.java:4442)
            at android.view.View$PerformClick.run(View.java:18473)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5105)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
            at dalvik.system.NativeStart.main(Native Method)
03-06 23:31:21.972    7620-7620/com.modup.app E/WORKOUTVIEW﹕ 2
03-06 23:31:21.982    7620-7620/com.modup.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.modup.app, PID: 7620
    java.lang.ClassCastException: com.modup.app.LeftMenusActivity cannot be cast to com.modup.view.WorkoutView$ButtonPressInterface
            at com.modup.view.WorkoutView.init(WorkoutView.java:70)
            at com.modup.view.WorkoutView.onFinishInflate(WorkoutView.java:52)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:763)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
            at com.modup.fragment.CreateFragment.onClick(CreateFragment.java:197)
            at android.view.View.performClick(View.java:4442)
            at android.view.View$PerformClick.run(View.java:18473)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5105)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
            at dalvik.system.NativeStart.main(Native Method)

在我期望响应回调的 Fragment 内部

@Override
public void buttonWasPressed() {
     workoutLayout.removeView(workoutView);
}

更新:

我实现了

   public void registerButtonPressInterface(ButtonPressInterface listener){
        buttonPressCallback = listener;
    }

这在添加视图时不会导致崩溃,但我的按钮仍然无法工作并导致 NullPointerException。

    @Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.btnRemoveWorkout:
            buttonPressCallback.buttonWasPressed();
            Log.e("DID THIS WORK?", "BUTTON PRESSED");
            break;
    }

}

这就是我尝试监听回调的方式

        workoutView.registerButtonPressInterface(new WorkoutView.ButtonPressInterface() {
        @Override
        public void buttonWasPressed() {
            Log.e("BUTTON WAS PRESSED", "INTERFACE WORKED!");
        }
    });
    workoutLayout.addView(workoutView);

【问题讨论】:

    标签: android view interface


    【解决方案1】:

    根据您的堆栈跟踪,这是导致胃灼热的行:

    buttonPressCallback = (ButtonPressInterface) getContext();

    您没有发布相关代码,但我敢打赌,您认为您的活动正在实现此接口,而实际上并非如此。其实你说你最后的代码sn-p(也就是接口实现)来自一个Fragment。

    这是我的建议:与其将上下文强制转换到您的界面,不如创建一个方法

    public void registerButtonPressListener(ButtonPressInterface listener)

    在您的视图类上并存储对ButtonPressInterface 实现的引用。这将使您的视图类更加灵活,因为您的上下文不需要实现ButtonPressInterface 即可使用您的视图。现在编译器将能够告诉您您传入的内容是否确实实现了接口,并且您将更容易找出问题所在。

    【讨论】:

    • 我用你的实现更新了这个问题,我遇到了一个空指针异常,我正在试图找出它。我相信这是因为从未真正创建过接口的实例。看看吧。
    • 你一定快到了。如果您在这三个代码点中设置断点,您应该能够弄清楚。所以您可以确保: 1. 您的监听器被存储在成员变量 buttonPressCallback 2. 当 onClick() 被调用时,buttonPressCallback 的值与它注册时的值相同 3. registerButtonPressListener() 在 onClick() 之前被调用
    • 我明白了,我已经成功了。我现在只需要跟踪每个实例,以便在按下按钮时删除正确的实例。
    猜你喜欢
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多