这是我的更正后的代码,仍然无法正常工作,这次我还包括了logcat以帮助识别我的错误。再次感谢您对我最后一个要求的惊人回应;

package com.example.michaelheneghan.example1;

import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.graphics.Color;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.Button;
import android.widget.TextView;
import android.view.MotionEvent;
import android.view.GestureDetector;
import android.support.v4.view.GestureDetectorCompat;
import android.widget.EditText;

import org.w3c.dom.Text;

public class MainActivity extends ActionBarActivity implements    GestureDetector.OnGestureListener,
    GestureDetector.OnDoubleTapListener{
//change back to TextView
    private Button mikesButton;
    private TextView mikesText;
    private GestureDetectorCompat gestureDetector;


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


    ////////// Layout object is added //////////////////
    RelativeLayout myLayout = new RelativeLayout(this);


    ////////// Button object being created /////////////////
    this.mikesButton = (Button) findViewById(R.id.mikesButton);
    this.mikesButton.setText("Click Me");
    this.mikesButton.setBackgroundColor(Color.RED);
    this.mikesText = (TextView)findViewById(R.id.mikesText);



    ///////// Set up an event listener for the button //////////////
    this.mikesButton.setOnClickListener(  /// listen for an event on this button
            new Button.OnClickListener() {   //// Interface
                public void onClick(View v) {    //// Callback method
                    TextView Change = (TextView) findViewById(R.id.mikesButton);
                    Change.setText("Good job, it changed!");
                }
            }
    );


    ///////////// Listening for multiple events ////////////////////
    mikesButton.setOnLongClickListener(
            new Button.OnLongClickListener(){   //// Interface
                public boolean onLongClick(View v) {    //// Callback method
                    TextView Change = (TextView) findViewById(R.id.mikesText);
                    Change.setText("Good job, it changed when you held onto the button!");
                    return true;
                }
            }
    );


    //////////// Set up an event listener for a double tap event //////////////
    mikesButton = (Button) findViewById(R.id.mikesButton); /////// Reference to the button
    this.gestureDetector = new GestureDetectorCompat(this,this); /// an object from GD class to detect gestures
    gestureDetector.setOnDoubleTapListener(this); /// Set method to detect double taps


    ///////// Input object called mikesText is added //////////////////////

    //mikesText.setId(2);


    RelativeLayout.LayoutParams textdeets = new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT
    );

    ///////// Give rules to position widgets ////////////////////////
    textdeets.addRule(RelativeLayout.ABOVE, mikesButton.getId()); /// Place above the button that is already centered//
    textdeets.addRule(RelativeLayout.CENTER_HORIZONTAL); //// place in the middle of the screen ////
    textdeets.setMargins(0, 0, 0, 50); ///// where to place; left, top, right, bottom ///////


    ////////////// Rules of where to place the layout object ///////////////
    RelativeLayout.LayoutParams buttonDeets = new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT
    );


    //////////// Rules of where to place the button object ////////////////
    buttonDeets.addRule(RelativeLayout.CENTER_HORIZONTAL);
    buttonDeets.addRule(RelativeLayout.CENTER_VERTICAL);


    ////////// Add widgets to layout and their rules///////////
    myLayout.addView(mikesButton, buttonDeets); //Second param shows android the rules of how it is layed out
    myLayout.addView(mikesText, textdeets);

}

////////////// implement gesture methods from GestureDetector class ///////////////////////

@Override
public boolean onDoubleTap(MotionEvent e) {
    mikesButton.setText("onDoubleTap");  /// set message to change text on screen to whatever gesture just occured
    return true; // return true on all gesture methods so the system shows the event was handled
}

@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
    mikesButton.setText("onSingleTapConfirmed");  /// set message to change text on screen to whatever gesture just occured
    return true;
}

@Override
public boolean onDoubleTapEvent(MotionEvent e) {
    mikesButton.setText("onDoubleTapEvent");
    return true;
}

@Override
public boolean onDown(MotionEvent e) {
    mikesButton.setText("onDown");
    return true;
}

@Override
public void onShowPress(MotionEvent e) {

}

@Override
public boolean onSingleTapUp(MotionEvent e) {
    mikesButton.setText("onSingleTapUp");
    return true;
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    mikesButton.setText("onScroll");
    return true;
}

@Override
public void onLongPress(MotionEvent e) {

}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    mikesButton.setText("onFling");
    return true;
}


////////// Override default method so that system checks if the event is a gesture before checking for common event /////////////
@Override
public boolean onTouchEvent(MotionEvent event) {
    this.gestureDetector.onTouchEvent(event); /// add the gesture detector variable to check for
    return super.onTouchEvent(event);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}


主要xml是:


<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="@string/stringMessage"
    android:id="@+id/mikesText"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="80dp" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/buttonName"
    android:id="@+id/mikesButton"
    android:layout_centerVertical="true"
    android:layout_alignRight="@+id/mikesText"
    android:layout_alignEnd="@+id/mikesText" />




我得到的日志是

10-09 11:16:47.471    5464-5464/com.example.michaelheneghan.example1 I/art﹕ Not late-enabling -Xcheck:jni (already on)
10-09 11:16:47.471    5464-5464/com.example.michaelheneghan.example1 I/art﹕ Late-enabling JIT
10-09 11:16:47.473    5464-5464/com.example.michaelheneghan.example1 I/art﹕ JIT created with code_cache_capacity=2MB compile_threshold=1000
10-09 11:16:47.497    5464-5464/com.example.michaelheneghan.example1 W/System﹕ ClassLoader referenced unknown path: /data/app/com.example.michaelheneghan.example1-2/lib/x86
10-09 11:16:47.599    5464-5464/com.example.michaelheneghan.example1 D/AndroidRuntime﹕ Shutting down VM
10-09 11:16:47.599    5464-5464/com.example.michaelheneghan.example1 E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.michaelheneghan.example1, PID: 5464
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.michaelheneghan.example1/com.example.michaelheneghan.example1.MainActivity}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
            at android.view.ViewGroup.addViewInner(ViewGroup.java:4309)
            at android.view.ViewGroup.addView(ViewGroup.java:4145)
            at android.view.ViewGroup.addView(ViewGroup.java:4117)
            at com.example.michaelheneghan.example1.MainActivity.onCreate(MainActivity.java:105)
            at android.app.Activity.performCreate(Activity.java:6237)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

最佳答案

我看到的第一件事是,您为按钮和textview(R.id.mikesButton)使用了相同的资源ID:

mikesButton = (Button) findViewById(R.id.mikesButton); /// ref to the location by id

public boolean onLongClick(View v) {    //// Callback method
     TextView Change = (TextView) findViewById(R.id.mikesButton);
     Change.setText("Good job, it changed when you held onto the button!");
     return true;
}


在某个时候应该给您强制转换例外。 @ geert-berkers这样的LogCat会很有帮助。

编辑



这是毫无价值的:

Button mikesButton = new Button(this);
mikesButton.setText("Click Me");
mikesButton.setBackgroundColor(Color.RED);
//mikesButton.setId(1);


由于它从未添加到布局中,因此,从xml布局activity_main扩展了臀部之后,您只是一行而已:

mikesButton = (Button) findViewById(R.id.mikesButton); /// ref to the location按ID

恢复它应该是:

Button mikesButton = (Button) findViewById(R.id.mikesButton);
mikesButton.setText("Click Me");
mikesButton.setBackgroundColor(Color.RED);
//mikesButton.setId(1); <-- never do this when inflating from xml R.id.mikesButton is already the id


另一个错误是您从未设置过mikesButton,mikesText属性,这就是为什么:

protected void onCreate(Bundle savedInstanceState) {
    ...
    Button mikesButton = new Button(this); //<-- this means you are using a local to the method an not the class property you define
    ...
}


它应该是 :

protected void onCreate(Bundle savedInstanceState) {
    ...
    this.mikesButton = (Button) findViewById(R.id.mikesButton);
    this.mikesText = (TextView) findViewById(R.id.mikesText); <-- Notice that i chaged the id so it should be changed on the activity_main layout
    ...
}


您已经使用设置了布局:

setContentView(R.layout.activity_main);


所以稍后再做:

/////// Sets this activities content to this view & change background color //////////
setContentView(myLayout);


将从您从xml加载的布局替换为您动态创建的布局,因此从xml加载的所有视图都不再位于活动布局中。

恢复所有更改:

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


    ////////// Button object being created /////////////////
    this.mikesButton = (Button) findViewById(R.id.mikesButton); /// ref to the location by id
    this.mikesButton.setText("Click Me");
    this.mikesButton.setBackgroundColor(Color.RED);

    ///////// Input object called mikesText is added //////////////////////
    this.mikesText = (TextView) findViewById(R.id.mikesText);


    ///////// Set up an event listener for the button //////////////
    this.mikesButton.setOnClickListener(  /// listen for an event on this button
            new Button.OnClickListener() {   //// Interface
                public void onClick(View v) {    //// Callback method
                    MainActivity.this.mikesText.setText("Good job, it changed!");
                }
            }
    );


    ///////////// Listening for multiple events ////////////////////
    this.mikesButton.setOnLongClickListener(
            new Button.OnLongClickListener() {   //// Interface
                public boolean onLongClick(View v) {    //// Callback method
                    MainActivity.this.mikesText.setText("Good job, it changed when you held onto the button!");
                    return true;
                }
            }
    );


    //////////// Set up an event listener for a double tap event //////////////
    this.gestureDetector = new GestureDetectorCompat(this, this); /// an object from GD class to detect gestures
    this.gestureDetector.setOnDoubleTapListener(this); /// Set method to detect double taps


    //TODO: if you want to add a button from code
    Button otherButton = new Button(this);
    otherButton.setText("Hey i was made by code");
    otherButton.setBackgroundColor(Color.BLUE);

    ////////////// Rules of where to place the layout object ///////////////
    RelativeLayout.LayoutParams buttonDeets = new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT
    );

    //////////// Rules of where to place the button object ////////////////
    buttonDeets.addRule(RelativeLayout.CENTER_HORIZONTAL);
    buttonDeets.addRule(RelativeLayout.CENTER_VERTICAL);

    RelativeLayout mainLayout = this.findViewById(R.id.mainLayout); //<-- you have to set the id property of the RelativeLayout on the xml file
    mainLayout.addView(otherButton,buttonDeets);

}


和布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/mikesButton"
        android:text="Button to press"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

    <TextView
        android:text="Text to change"
        android:id="@+id/mikesText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/mikesButton"
        android:layout_centerHorizontal="true"
        android:textAppearance="?android:textAppearanceLarge"/>
</RelativeLayout>


@ geert-berkers我偷了您的xml导致太懒了以至于无法自己做一个:p

编辑2:已更改的问题

您现在遇到的错误是由于:

////////// Add widgets to layout and their rules///////////
myLayout.addView(mikesButton, buttonDeets); //Second param shows android the rules of how it is layed out
myLayout.addView(mikesText, textdeets);


在这里,您说的是要将mikesButton和mikesText添加到通过代码创建的myLayout中,但是按钮已经是从xml(使用setContentView(R.layout.activity_main);)加载的布局的一部分。
我不明白您要通过这样做来实现什么。如果要通过代码添加新视图,请不要使用findViewById(R.id.mikesButton);,而应使用new Button(this)创建一个新实例。 findViewById尝试查找已经在视图组的层次结构中的视图,在这种情况下,视图组是活动的布局。
看一下// TODO:我给您的部分代码,注意与您在此处所做的不同。
还要避免在不同的对象上使用相同的引用,因为这会使您感到困惑。

别 :

this.mikesButton = (Button) findViewById(R.id.mikesButton);
// Later ...
this.mikesButton = new Button(this);
// So now you lost the reference to the previous object


改为:

this.mikesButton = (Button) findViewById(R.id.mikesButton);
// Later ...
Button otherButton = new Button(this);
// You can still reference the precious object and u know that mikesButton is the one you loaded from the xml layout

07-24 09:45