Как правильно реализовать onClickItem из списка поисковых действий

У меня есть поисковая активность (ActivitySearch.java), которая правильно возвращает результаты, когда я использую кнопку «Перейти» на программной клавиатуре, она возвращает все результаты из предложений поиска. Я использую Content Provider и Cursor LoaderCallbacks. Это мой первый раз, когда я пытаюсь использовать LoaderCallbacks и занимаюсь поиском.

Теперь я хочу иметь возможность щелкнуть один из предложенных результатов через onClickItem/onClickItemListenter и вернуть его в список поиска для окончательного выбора пользователем, но я знаю, что мой код неверен, очевидно. К вашему сведению, я включил все свои действия в проекте как доступные для поиска. Я просмотрел кучу образцов, но не смог подобрать правильный метод.

Я использую простую активность (ActivityFloor.java), в которой я нажимаю клавишу поиска оборудования, всего несколько кнопок, которые запускают намерения.

Моя поисковая активность использует представление Android по умолчанию для результатов списка. Он также наследует свою активность от MyListActivity, но это для поддержки общего меню.

Вот мой манифест:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.birdsall.tda"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="17" />

<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.camera" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme"
    android:uiOptions="splitActionBarWhenNarrow"
     android:exported="true" >

    <meta-data android:name="com.google.android.apps.drive.APP_ID" android:value="id=12345" />

    <intent-filter>
    <action android:name="com.google.android.apps.drive.DRIVE_OPEN" />
    <data android:mimeType="application/vnd.google-apps.drive-sdk.12345" />
    <data android:mimeType="image/png" />
    <data android:mimeType="image/jpeg" />
    <data android:mimeType="image/jpg" />
    </intent-filter>

    <meta-data
        android:name="android.app.default_searchable"
        android:value=".ActivitySearch" />

    <activity
        android:name="com.birdsall.tda.ActivityMain"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name=".ActivityFloor" >
    </activity>


    <provider
        android:name="com.birdsall.tda.TDAProvider"
        android:authorities="com.birdsall.tda.contentprovidertda"
        android:exported="true"
        android:readPermission="true"
        android:writePermission="true" />

    <activity
        android:name=".ActivitySearch"
        android:label="Rule Search"
        android:launchMode="singleTop" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />
    </activity>
</application>

</manifest>

Вот мой searchable.xml в res/xml

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:searchSettingsDescription="@string/search_description"
android:searchSuggestAuthority="com.birdsall.tda.contentprovidertda"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestIntentData="content://com.birdsall.tda.TDAProvider/rules"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" >

</searchable>

Вот моя поисковая активность (ActivitySearch.java):

package com.birdsall.tda;

import android.app.Activity;
import android.app.LoaderManager;
import android.app.SearchManager;
import android.content.ContentUris;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class ActivitySearch extends MyListActivity implements 
    LoaderManager.LoaderCallbacks<Cursor> {


private static String QUERY_EXTRA_KEY = "QUERY_EXTRA_KEY";

private SimpleCursorAdapter adapter;
private final String TAG = "ActivitySearch";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i(TAG, "onCreate");

    View mListView  = getListView();

    Log.i(TAG, "onCreate ... after setOnItemClickListener");

    Toast.makeText(getApplicationContext(), "onCreate ... after setOnItemClickListener", Toast.LENGTH_LONG).show();

    // Create a new adapter and bind it to the List View
    adapter = new SimpleCursorAdapter(this,
            android.R.layout.simple_list_item_1, null,
            new String[] { TDAdb.COL_RULETITLE },
            new int[] { android.R.id.text1 }, 0);
    setListAdapter(adapter);

    // Initiate the Cursor Loader
    getLoaderManager().initLoader(0, null, this);

    // Get the launch Intent
    parseIntent(getIntent());
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    Log.i(TAG, "onNewIntent");
    Toast.makeText(getApplicationContext(), "onNewIntent", Toast.LENGTH_LONG).show();
    parseIntent(getIntent());

}



private void parseIntent(Intent intent) {
    // If the Activity was started to service a Search request,
    // extract the search query.
    Log.i(TAG, "parseIntent");
    Toast.makeText(getApplicationContext(), "parseIntent", Toast.LENGTH_LONG).show();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String searchQuery = intent.getStringExtra(SearchManager.QUERY);

        // Perform the search, passing in the search query as an argument
        // to the Cursor Loader
        Bundle args = new Bundle();
        args.putString(QUERY_EXTRA_KEY, searchQuery);

        // Restart the Cursor Loader to execute the new query.
        getLoaderManager().restartLoader(0, args, this);
    }
}

public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    Log.i(TAG, "onCreateLoader");
    Toast.makeText(getApplicationContext(), "onCreateLoader", Toast.LENGTH_LONG).show();
    String query = "0";

    if (args != null) {
        // Extract the search query from the arguments.
        query = args.getString(QUERY_EXTRA_KEY);
    }

    // Construct the new query in the form of a Cursor Loader.
    String[] projection = { TDAdb.KEY_ROWID, TDAdb.COL_RULETITLE };
    String where = TDAdb.COL_RULETITLE + " LIKE \"%" + query + "%\"";
    String[] whereArgs = null;
    String sortOrder = TDAdb.COL_RULETITLE;

    // Create the new Cursor loader.
    return new CursorLoader(this, TDAProvider.CONTENT_URI_RULES,
            projection, where, whereArgs, sortOrder);
}

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    // Replace the result Cursor displayed by the Cursor Adapter with
    // the new result set.
    Log.i(TAG, "onLoadFinished");
    Toast.makeText(getApplicationContext(), "onLoadFinished", Toast.LENGTH_LONG).show();

    if (adapter == null) {
        Log.i(TAG, "onLoadFinished ... adapter is NULL");
        Toast.makeText(getApplicationContext(), "onLoadFinished ... adapter is NULL", Toast.LENGTH_LONG).show();
        this.finish();
    } 
    Log.i(TAG, "onLoadFinished ... adapter is valued");
    Toast.makeText(getApplicationContext(), "onLoadFinished ... adapter is valued", Toast.LENGTH_LONG).show();

    adapter.swapCursor(cursor);     

}

public void onLoaderReset(Loader<Cursor> loader) {
    // Remove the existing result Cursor from the List Adapter.
    Log.i(TAG, "onLoaderReset");
    Toast.makeText(getApplicationContext(), "onLoaderReset", Toast.LENGTH_LONG).show();
    adapter.swapCursor(null);
}

private void handleIntent(Intent intent) {
    Log.i(TAG, "handleIntent");
    Toast.makeText(getApplicationContext(), "handleIntent", Toast.LENGTH_LONG).show();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        // Gets the search query from the voice recognizer intent
        String query = intent.getStringExtra(SearchManager.QUERY);

        // Set the search box text to the received query and submit the
        // search
        // mSearchView.setQuery(query, true);
    }
}

  @Override
  protected void onListItemClick(ListView listView, View view, int position, long id) {
    super.onListItemClick(listView, view, position, id);
    Toast.makeText(getApplicationContext(), 
    " search listview position:" + position,
    Toast.LENGTH_LONG).show();
    // Create a URI to the selected item.
    Uri selectedUri = 
      ContentUris.withAppendedId(TDAProvider.CONTENT_URI, id);

    // Create an Intent to view the selected item.
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(selectedUri);

    // Start an Activity to view the selected item.
    startActivity(intent);
  }

}

Я БОЛЬШЕ НЕ ПОЛУЧАЮ ОШИБОК, СПАСИБО Майклу (ниже), поэтому ошибки LOGCAT можно игнорировать.

Я получаю ошибки, но только после попытки реализовать кодирование onClickItem из моего логарифма, который я включил для полноты картины.

06-2923:56:57.416: I/TDAProvider(13786): query 
06-2923:56:57.439: W/SuggestionsAdapter(13786): Search suggestions query threw an exception.
06-2923:56:57.439: W/SuggestionsAdapter(13786): java.lang.IndexOutOfBoundsException
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.net.Uri$PathSegments.get(Uri.java:978)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.net.Uri$PathSegments.get(Uri.java:963)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at com.birdsall.tda.TDAProvider.query(TDAProvider.java:180)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.content.ContentProvider.query(ContentProvider.java:652)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.content.ContentProvider$Transport.query(ContentProvider.java:189)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.content.ContentResolver.query(ContentResolver.java:370)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.content.ContentResolver.query(ContentResolver.java:313)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.app.SearchManager.getSuggestions(SearchManager.java:823)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.widget.SuggestionsAdapter.runQueryOnBackgroundThread(SuggestionsAdapter.java:190)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.widget.CursorFilter.performFiltering(CursorFilter.java:49)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.os.Looper.loop(Looper.java:137)
06-2923:56:57.439: W/SuggestionsAdapter(13786):     at android.os.HandlerThread.run(HandlerThread.java:60)
06-2923:57:00.002: I/TDAProvider(13786): query 
06-2923:57:00.049: I/TDAProvider(13786): query return cursor 
06-2923:57:00.635: I/TDAProvider(13786): query 
06-2923:57:00.635: I/TDAProvider(13786): query return cursor 
06-2923:57:01.275: I/TDAProvider(13786): query 
06-2923:57:01.275: I/TDAProvider(13786): query return cursor 
06-2923:57:02.650: W/InputEventReceiver(13786): Attempted to finish an input event but the input event receiver has already been disposed.
06-2923:57:02.689: I/ActivitySearch(13786): onCreate
06-2923:57:02.728: D/AndroidRuntime(13786): Shutting down VM
06-2923:57:02.728: W/dalvikvm(13786): threadid=1: thread exiting with uncaught exception (group=0x40e1b2a0)
06-2923:57:02.728: E/AndroidRuntime(13786): FATAL EXCEPTION: main
06-2923:57:02.728: E/AndroidRuntime(13786): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.birdsall.tda/com.birdsall.tda.ActivitySearch}: java.lang.ClassCastException: com.birdsall.tda.ActivitySearch cannot be cast to android.view.View$OnClickListener
06-2923:57:02.728: E/AndroidRuntime(13786):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2136)
06-2923:57:02.728: E/AndroidRuntime(13786):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2174)
06-2923:57:02.728: E/AndroidRuntime(13786):     at android.app.ActivityThread.access$700(ActivityThread.java:141)
06-2923:57:02.728: E/AndroidRuntime(13786):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1267)
06-2923:57:02.728: E/AndroidRuntime(13786):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-2923:57:02.728: E/AndroidRuntime(13786):     at android.os.Looper.loop(Looper.java:137)
06-2923:57:02.728: E/AndroidRuntime(13786):     at android.app.ActivityThread.main(ActivityThread.java:5059)
06-2923:57:02.728: E/AndroidRuntime(13786):     at java.lang.reflect.Method.invokeNative(Native Method)
06-2923:57:02.728: E/AndroidRuntime(13786):     at java.lang.reflect.Method.invoke(Method.java:511)
06-2923:57:02.728: E/AndroidRuntime(13786):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
06-2923:57:02.728: E/AndroidRuntime(13786):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
06-2923:57:02.728: E/AndroidRuntime(13786):     at dalvik.system.NativeStart.main(Native Method)
06-2923:57:02.728: E/AndroidRuntime(13786): Caused by: java.lang.ClassCastException: com.birdsall.tda.ActivitySearch cannot be cast to android.view.View$OnClickListener
06-2923:57:02.728: E/AndroidRuntime(13786):     at com.birdsall.tda.ActivitySearch.onCreate(ActivitySearch.java:39)
06-2923:57:02.728: E/AndroidRuntime(13786):     at android.app.Activity.performCreate(Activity.java:5058)
06-2923:57:02.728: E/AndroidRuntime(13786):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
06-2923:57:02.728: E/AndroidRuntime(13786):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2100)
06-2923:57:02.728: E/AndroidRuntime(13786):     ... 11 more
06-2923:57:04.392: I/Process(13786): Sending signal. PID: 13786 SIG: 9

Спасибо за время и помощь, заранее.

Вот суть MyActivity, просто общее меню для моих действий.

package com.birdsall.tda;

import android.app.ListActivity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;

public class MyListActivity extends ListActivity {

String selectParam = "";

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()) {
    case android.R.id.home:
          Intent intent = new Intent(this, ActivityMain.class);
          intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
          startActivity(intent);
          return true;

    case R.id.am_index:
        Intent i1 = new Intent(this, ActivityIndex.class);
        startActivity(i1);
        return true;    

        /*  ...    More menu items */

    default:
        return super.onOptionsItemSelected(item);
    }

}
}

person Peter Birdsall    schedule 30.06.2013    source источник
comment
что такое MyListActivity?   -  person Raghunandan    schedule 30.06.2013
comment
Я упомянул об этом выше, это переопределение Activity, у него просто общая информация меню, я добавил источник.   -  person Peter Birdsall    schedule 30.06.2013
comment
Я взял работающее действие поиска из другого проекта и заменил им свой код, и все равно получаю те же результаты.   -  person Peter Birdsall    schedule 04.07.2013


Ответы (2)


попробуй это

@Override
public void onListItemClick( ListView parent, View v, int position, long id)
{ 
//...
}

в твоем Activity

вам не нужно устанавливать listener для этого

надеюсь это поможет..

person Michael Shrestha    schedule 30.06.2013
comment
Eclipse жалуется на это: 'Метод setOnClickListener(View.OnClickListener) в типе View неприменим для аргументов (ActivitySearch)', поэтому я изменил его на следующее: 'mListView.setOnClickListener((OnClickListener) this);' но все равно бомбит. Я думаю, что либо у меня неправильно определен mListView, либо есть класс поиска, который я должен переопределить. Спасибо за предложение. - person Peter Birdsall; 30.06.2013
comment
Я получил ваше предложение остановить программу от бомбардировки, но я все еще ничего не вижу в своем списке после выбора элемента. Я обновляю оригинальный ActivitySearch. - person Peter Birdsall; 01.07.2013

Я потратил на это около 2 недель, и мой код немного изменился. Я обнаружил, что setContentView и мой локальный макет были причиной отсутствия результатов. Выложу новую версию кода. Спасибо всем.

package com.birdsall.tda;

import android.app.LoaderManager;
import android.app.SearchManager;
import android.app.SearchableInfo;
import android.content.ContentUris;
import android.content.Context;
import android.content.CursorLoader;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class ActivitySearch extends MyListActivity implements
    LoaderManager.LoaderCallbacks<Cursor> {

private static String QUERY_EXTRA_KEY = "QUERY_EXTRA_KEY";
private static final String TAG = "ActivitySearch";

private SimpleCursorAdapter adapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Log.i(TAG, "onCreate");

    adapter = new SimpleCursorAdapter(this,
            android.R.layout.simple_list_item_1, null,
            new String[] { TDAdb.COL_RULETITLE },
            new int[] { android.R.id.text1 }, 0);
    setListAdapter(adapter);

    getLoaderManager().initLoader(0, null, this);

    parseIntent(getIntent());


    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchableInfo searchableInfo = searchManager
            .getSearchableInfo(getComponentName());

    Log.i(TAG, "onCreate at end");

}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    Log.i(TAG, "onNewIntent");
    parseIntent(getIntent());
}

private void parseIntent(Intent intent) {

    Log.i(TAG, "parseIntent");

    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String searchQuery = intent.getStringExtra(SearchManager.QUERY);
        // Perform the search
        performSearch(searchQuery);
    }
}

private void performSearch(String query) {
    Log.i(TAG, "performSearch");
    Bundle args = new Bundle();
    args.putString(QUERY_EXTRA_KEY, query);

    getLoaderManager().restartLoader(0, args, this);
}

public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String query = "0";
    Log.i(TAG, "onCreateLoader");
    if (args != null)
        query = args.getString(QUERY_EXTRA_KEY);

    String[] projection = { TDAdb.KEY_ROWID, TDAdb.COL_RULETITLE };
    String where = TDAdb.COL_RULETITLE + " LIKE \"%" + query + "%\"";

    String[] whereArgs = null;
    String sortOrder = TDAdb.COL_RULETITLE;

    return new CursorLoader(this, TDAProvider.CONTENT_URI_RULES,
            projection, where, whereArgs, sortOrder);
}

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {

    adapter.swapCursor(cursor);
    adapter.notifyDataSetChanged();

    Log.i(TAG, "onLoadFinished ... cursor has " + cursor.getCount()
            + " row(s)");
                + " row(s)", Toast.LENGTH_SHORT).show();
}

public void onLoaderReset(Loader<Cursor> loader) {
    Log.i(TAG, "onLoaderReset");
    adapter.swapCursor(null);
}

/**
 * Listing 8-28: Providing actions for search result selection
 */
@Override
protected void onListItemClick(ListView listView, View view, int position,
        long id) {
    super.onListItemClick(listView, view, position, id);

    Log.i(TAG, "onListItemClick");

    Uri selectedUri = ContentUris.withAppendedId(
            TDAProvider.CONTENT_URI_RULES, id);

    Intent i = new Intent(ActivitySearch.this, ActivityRulesCrossRef.class);
    Bundle extras = new Bundle();
    extras.putString("XRef", "N");
    String str_rowid = String.valueOf(id);
    extras.putString("selectedID", str_rowid);
    extras.putString("selectedRule", "Search");
    i.putExtras(extras);
    startActivity(i);
    finish();

}

public void onDismiss(final DialogInterface arg0) {
    finish();
}

}
person Peter Birdsall    schedule 20.07.2013