Как запустить Intent из OnClickListener

Моя основная активность расширяет ListActivity и отображает список. Я использую пользовательские элементы списка, определенные в классе с именем DefinitionAdapter. У меня также есть отдельный класс, который реализует OnClickListener.

В классе DefinitionAdapter я установил OnClickListener в 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;
   }

Мой пользовательский OnClickListener должен запускать другое действие.

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);

    }

}

Я не уверен, что делаю это правильно. Я добавил свою новую активность в манифест, а также активность, с помощью которой я расширил прослушиватель:

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

Тем не менее, если я нажму на элемент в своем списке, приложение всегда прерывается с NullPointerException. Я думаю, что неправильно использую намерение... есть идеи?

По поводу комментария Никиты Белоглазова:

Он ломается, когда я создаю намерение:

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

Вот трассировка стека:

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)

person AndiH    schedule 23.05.2011    source источник
comment
На какой строке, если точно обрывается? Не могли бы вы опубликовать трассировку стека?   -  person Mikita Belahlazau    schedule 24.05.2011
comment
Я добавил эту информацию   -  person AndiH    schedule 24.05.2011


Ответы (3)


Ваш OnItemClickListener не должен расширять Activity. Вместо этого вы должны организовать доступ OnItemClickListener к вашему экземпляру ListActivity. Любое представление, которое уже является частью активности (например, ListView), имеет доступ к экземпляру ListActivity через getContext(). Затем реализуйте onClick следующим образом:

@Override
public void onClick(View v) {
    Intent intent = new Intent(context, ShowDefinition.class);
    context.startActivity(intent);
}
person Ted Hopp    schedule 23.05.2011
comment
Это действительно помогает. Я уже пробовал: Intent intent = new Intent(v.getContext(), ShowDefinition.class); Но затем я запускаю намерение с помощью startActivit(intent). Теперь я использую v.getContext().startActivity(intent), который помогает. Спасибо! - person AndiH; 24.05.2011
comment
Рад, что это сработало. На самом деле гораздо лучший подход — переопределить onListItemClicked в вашем подклассе ListActivity. Тогда вам не нужны прослушиватели кликов. (P.S. Если вы еще этого не сделали, не забудьте удалить OnItemClickListener из списка активностей в манифесте.) - person Ted Hopp; 24.05.2011
comment
Я так и сделал, следуя инструкциям I_Artist. Это действительно намного лучше. Наверное, я просто не нашел правильных инструкций ListActivity. Надо было внимательнее читать документацию. Спасибо за помощь. - person AndiH; 24.05.2011
comment
@twittfort спасибо !, он отлично работает, когда отображается список, когда я интегрирую фильтр поиска в пользовательский адаптер массива, после отображения результата поиска (notifyDataSetChanged();) в представлении списка, когда я нажимаю на элемент, происходит сбой при вызове Intent, любое решение для это? - person LOG_TAG; 14.01.2013

Есть два способа реализовать onItemClickListener. Вам не нужно создавать новый класс. Может быть, вы можете попробовать это простой способ сейчас :)

Пусть ваша ListActivity реализует AdapterView.OnItemClickListener

public class MyActivity extends ListActivity implements AdapterView.OnItemClickListener

Затем в onCreate вашего ListActivity установите свой onClickListener следующим образом:

        ListView lstvwContacts = getListView();
        lstvwContacts.setOnItemClickListener(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);
        }    
    }
}

Это должно сделать это для кликов. Если вам нужно знать, когда элемент выбран, вы можете заглянуть в AdapterView.OnItemSelectedListener.

-I_Artist

person MikeWallaceDev    schedule 23.05.2011
comment
Спасибо. Я ценю это решение. Я постараюсь реализовать это таким образом в будущем. Я сделал дополнительный класс для более легкого понимания концепции. - person AndiH; 24.05.2011
comment
Хорошо, теперь я попробовал ваше решение. Это действительно намного проще! У меня просто возникли проблемы с реализацией AdapterView.OnItemClickListener. Эклипс не нашел. Мне пришлось реализовать android.widget.AdapterView.OnItemClickListener - person AndiH; 24.05.2011

Ваша концепция неверна, ваш OnItemClickListener не должен расширять Activity, и вы не должны каждый раз создавать новый onClickListener.

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

   }
}
person vieux    schedule 23.05.2011