How do I start an Intent from an OnClickListener

2019-02-11 21:31发布

问题:

My Main Activity extends ListActivity and displays a List. I am using custom Listitems defined in a class named DefinitionAdapter. I also have a seperate class that implements OnClickListener.

In the class DefinitionAdapter I set the OnClickListener to the ListItems:

   public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater)getContext().getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.row, null);
        }
...

        v.setOnClickListener(new OnItemClickListener(position) );

        return v;
   }

My custom OnClickListener is supposed to start another activity.

public class OnItemClickListener implements OnClickListener extends Activity {


    private int position;

    public OnItemClickListener(int p) {

        position = p;   
    }

    @Override
    public void onClick(View v) {

        Intent intent = new Intent(this, ShowDefinition.class);
        startActivity(intent);

    }

}

I am not sure that I am doing that right. I added my new activity to the manifest, as well as the activity i extended the listener with:

<activity android:name="ShowDefinition" android:label="@string/app_name">
</activity>
<activity android:name="OnItemClickListener" android:label="@string/app_name">
</activity>    

Nonetheless, if I click on an Item in my List, the application always breaks with a NullPointerException. I think I am using the intent wrong... any Ideas?

In regard to Nikita Beloglazov's comment:

It breaks when I create the Intent:

Intent intent = new Intent(this, ShowDefinition.class);

Here's the stacktrace:

05-23 22:56:46.629: ERROR/AndroidRuntime(258): Uncaught handler: thread main exiting due to uncaught exception
05-23 22:56:46.659: ERROR/AndroidRuntime(258): java.lang.NullPointerException
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.content.ContextWrapper.getPackageName(ContextWrapper.java:120)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.content.ComponentName.<init>(ComponentName.java:75)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.content.Intent.<init>(Intent.java:2551)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at com.andiandy.juradefinitions.OnItemClickListener.onClick(OnItemClickListener.java:22)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.view.View.performClick(View.java:2364)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.view.View.onTouchEvent(View.java:4179)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.view.View.dispatchTouchEvent(View.java:3709)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:852)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1659)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.app.Activity.dispatchTouchEvent(Activity.java:2061)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1643)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1691)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.os.Looper.loop(Looper.java:123)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at android.app.ActivityThread.main(ActivityThread.java:4363)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at java.lang.reflect.Method.invokeNative(Native Method)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at java.lang.reflect.Method.invoke(Method.java:521)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
05-23 22:56:46.659: ERROR/AndroidRuntime(258):     at dalvik.system.NativeStart.main(Native Method)

回答1:

Your OnItemClickListener should not extend Activity. Instead, you should arrange for the OnItemClickListener to have access to your ListActivity instance. Any view that is already part of the activity (like the ListView) has access to the ListActivity instance via getContext(). Then implement onClick like this:

@Override
public void onClick(View v) {
    Intent intent = new Intent(context, ShowDefinition.class);
    context.startActivity(intent);
}


回答2:

There are two ways to implement an onItemClickListener. You don't need to create a new class. Maybe you can try it the easy way for now :)

Have your ListActivity implement AdapterView.OnItemClickListener

public class MyActivity extends ListActivity implements AdapterView.OnItemClickListener

Then in your ListActivity's onCreate set your onClickListener like this :

        ListView lstvwContacts = getListView();
        lstvwContacts.setOnItemClickListener(this);

And then you can react to the click like this :

public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
    switch (parent.getId()) {
        case android.R.id.list: {
            Log.v(TAG, "onItemClick");
            Intent intent = new Intent(this, ShowDefinition.class);
            startActivity(intent);
        }    
    }
}

That should do it for clicks. If you need to know when an item is selected you can look into AdapterView.OnItemSelectedListener

-I_Artist



回答3:

Your conception is wrong, your OnItemClickListener shouldn't extends Activity and you should n't build a new onClickListener each time.

public class MainActivity extends Activity {
    OnItemClickListener = null;

   MainActivity() {
    //Build your OnItemClickListener with a valid context
    OnItemClickListener = new OnItemClickListener(this);
   }

   public View getView(int position, View convertView, ViewGroup parent) {
   ...

   //Here user the OnItemClickListener

   }
}