【问题标题】:onTouchListener() in Android not called after including ImageView from BaseActivity-XML包含来自 BaseActivity-XML 的 ImageView 后未调用 Android 中的 onTouchListener()
【发布时间】:2016-02-04 16:00:19
【问题描述】:

下面的代码展示了一个抽象的Activity(AppActivity),其他的Activity都得从其扩展而来。已经定义了一个布局,但只继承了一个圆形按钮(扩展 ImageView)。

MainActivity 定义了一个自己的布局,它必须包含前面提到的按钮。查看我目前的结果,Button成功被继承并显示,不能为空

尽管如此,附加到此 ImageView 的 onTouchListener() 永远不会从视角“MainActivity”调用。请注意,如果 MotionEvent.ACTION_DOWN 和 UP 发生,我会返回 true。所以这不可能是原因。有什么建议吗?

带有 CircleButton 的抽象 Activity(扩展 ImageView)包括 onTouchListener()

public abstract class AppActivity extends Activity {

    public CircleButton circleButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.voice_btn_layout);

        circleButton = (CircleButton) findViewById(R.id.voiceControlBtn);

        circleButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.i("TOUCH", "");
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    ButtonGotPressed();
                    return true;
                } else if (event.getAction() == MotionEvent.ACTION_UP) {
                    circleButton.ButtonGotReleased();
                    return true;
                }
                return false;
            }
        });
}

从 AppActivity 扩展的 Activity

  public class MainActivity extends AppActivity implements ICadeCommand {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(eu.alfred.batterywarnerapp.R.layout.activity_main);
        }

activity_main.xml(用于 MainActivity)

<RelativeLayout .../>

    <include layout="@layout/voice_btn_layout" />

</RelativeLayout>

voice_btn_layout.xml(用于 AppActivity)

    <FrameLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="80dip"
            android:layout_height="80dip"
            android:layout_margin="15dip"
            android:layout_alignParentEnd="true"
            android:layout_alignParentBottom="true">

            <packagename.CircleButton
                ...
                android:scaleType="fitXY"/>

    </FrameLayout>

【问题讨论】:

    标签: java android xml inheritance ontouchlistener


    【解决方案1】:

    您在R.layout.voice_btn_layout 中为circleButton 设置OnTouchListener

    当您在MainActivity 中调用setContentView() 时,会将布局R.layout.voice_btn_layout 替换为eu.alfred.batterywarnerapp.R.layout.activity_main。因此不会调用AppActivitycircleButtononTouch() 方法,因为屏幕上显示的circleButtonAppActivity 中的circleButton 不同。

    您可以通过在AppActivity 中添加额外的行来测试是否确实如此

    public abstract class AppActivity extends Activity {
    
    public CircleButton circleButton;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.voice_btn_layout);
    
        circleButton = (CircleButton) findViewById(R.id.voiceControlBtn);
        circleButton.setVisibility(View.GONE);     // ADD THIS LINE 
        circleButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
            ...
    

    您应该注意到circleButton 仍然可见,因此表明屏幕上显示的circleButtonAppActivity 中的不一样。

    【讨论】:

    • 确定我要“替换”布局?我只是包括它。 activity_main.xml 是那个特殊的按钮布局,期望它现在被另一个 RelativeLayout 包裹
    • @GaryKlasen 是的,我很确定 R.layout.voice_btn_layoutactivity_main.xml 取代。 setContentView() 只是扩充一个新布局并将其设置为此Activity 的布局。是的,您确实在AppActivityonCreate() 中添加了一个侦听器,但是当您在MainActivityonCreate() 中再次调用setContentView() 时,一个包含新R.layout.voice_btn_layout 的新eu.alfred.batterywarnerapp.R.layout.activity_main 布局被膨胀并替换之前设置的R.layout.voice_btn_layout
    • 那么如何在不覆盖引用的情况下包含它?
    • @GaryKlasen 通过不在MainActivityonCreate() 中调用setContentView(),尽管我怀疑这是您想要实现的目标。如果您想在AppActivity 的所有子类上调用setOnTouchListener(),我建议您将设置的侦听器代码放在AppActivity 中的单独方法(例如setupCircleButton())中,并在MainActivity 中调用super.setupCircleButton() onCreate() 之后 setContentView().
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多