如何在 json 对象的列表视图中搜索?

Posted

技术标签:

【中文标题】如何在 json 对象的列表视图中搜索?【英文标题】:How can I search within a listview of json objects? 【发布时间】:2019-10-19 01:12:35 【问题描述】:

我有一个列表视图,其中填充了使用改造从 URL 获取的 json 对象。

每个对象都有一个在单击对象时显示的详细信息页面。

如何在列表视图中搜索对象并通过单击结果显示正确的对象及其详细信息页面?

我已经尝试了 searchview,我认为它只是一个过滤器而不是真正的搜索,因为它只显示与我插入的搜索字符串匹配的对象,但是当我点击一个过滤的对象时,它仍然给我最初列出的项目位置。

公共类 SearchTafelnActivity 扩展 AppCompatActivity

SearchView sv;



private List<TafelnCall> tafelItems;
private ArrayAdapter<String> adapter;
private ProgressBar progressBar;


@Override
public boolean onCreateOptionsMenu(Menu menu) 
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);

    // Associate searchable configuration with the SearchView
    SearchManager searchManager =
            (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView =
            (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setSearchableInfo(
            searchManager.getSearchableInfo(getComponentName()));

    return true;


@Override
protected void onNewIntent(Intent intent) 

    handleIntent(intent);


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

    progressBar = findViewById(R.id.pBar);
    progressBar.setVisibility(View.VISIBLE);

    handleIntent(getIntent());


    /*final SearchView searchView = (SearchView) findViewById(R.id.searchView);
    searchView.onActionViewExpanded();
    searchView.setIconified(true);


    searchView.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            searchView.setIconified(false);
        
    );*/





        BottomNavigationView navigation = findViewById(R.id.bot_nav);
        BottomNavigationViewHelper.disableShiftMode(navigation);//Dont forgot this line

        Menu menu = navigation.getMenu();
        MenuItem menuitem = menu.getItem(3);
        menuitem.setChecked(true);

    //Switch activities
        navigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() 
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) 
                switch(item.getItemId())
                    case R.id.nav_home:

                     Intent intent0 = new Intent(SearchTafelnActivity.this, MainActivity.class);
                    startActivity(intent0);
                    break;

                    case R.id.nav_news:

                    Intent intent1 = new Intent(SearchTafelnActivity.this, NewsActivity.class);
                    startActivity(intent1);
                        break;

                    case R.id.nav_money:

                    Intent intent2 = new Intent(SearchTafelnActivity.this, DonateActivity.class);
                    startActivity(intent2);
                        break;

                    case R.id.nav_search:

                    /*Intent intent3 = new Intent(SearchTafelnActivity.this, SearchTafelnActivity.class);
                    startActivity(intent3);*/
                        break;


                
                return false;
            
        );



        final ListView listView = (ListView) findViewById(R.id.listView);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
                TafelnCall tafelitem = tafelItems.get(position);
                Intent intent = new Intent(SearchTafelnActivity.this, TafelDetailPage.class);

                String tName = tafelitem.getName();
                String tAdress = tafelitem.getAddress();
                String tContact = tafelitem.getContactPerson();
                String tPhone = tafelitem.getPhone1();
                String tMail = tafelitem.getEmail();
                String tLong = tafelitem.getLongitude();
                String tLat = tafelitem.getLatitude();
                String tStreet = tafelitem.getAddress();
                String tZip = tafelitem.getZip();

                intent.putExtra( "key_tName", tName);
                intent.putExtra( "key_tAdress", tAdress);
                intent.putExtra( "key_tContact", tContact);
                intent.putExtra( "key_tPhone", tPhone);
                intent.putExtra( "key_tMail", tMail);
                intent.putExtra("key_tLong", tLong );
                intent.putExtra("key_tLat", tLat);
                intent.putExtra("key_tStreet", tStreet);
                intent.putExtra("key_tZip", tZip);


                startActivity(intent);

            
        );

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Api.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        Api api = retrofit.create(Api.class);

        Call<List<TafelnCall>> call = api.getTafeln();



        call.enqueue(new Callback<List<TafelnCall>>() 

            @Override
            public void onResponse(Call<List<TafelnCall>> call, Response<List<TafelnCall>> response) 

                tafelItems = response.body();

                final String [] tafelNames = new String[tafelItems.size()];

                for(int i =0; i< tafelItems.size(); i++)
                    final TafelnCall tafelnCall = tafelItems.get(i);
                    tafelNames[i] = tafelnCall.getName();
                  /*tafelNames[i] = tafelnCall.getAddress();
                    tafelNames[i] = tafelnCall.getAddressAdd();
                    tafelNames[i] = tafelnCall.getCarrier();
                    tafelNames[i] = tafelnCall.getCategory();
                    tafelNames[i] = tafelnCall.getCity();*/




                

                adapter = new ArrayAdapter<>(
                        getApplicationContext(),
                        R.layout.listitem,
                        tafelNames
                );

                listView.setAdapter(adapter);

                progressBar.setVisibility(View.GONE);


                //Search function start
                sv = findViewById(R.id.searchView);
                sv.setQueryHint("Suche");
                sv.setOnClickListener(new View.OnClickListener() 
                    @Override
                    public void onClick(View v) 
                        sv.setIconified(false); //makes whole searchview clickable
                    
                );


                sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() 
                    @Override
                    public boolean onQueryTextSubmit(String text) 
                        return false;
                    

                    @Override
                    public boolean onQueryTextChange(String text) 
                        adapter.getFilter().filter(text);



                        return false;
                    
                );



                ////Search function end



            



            @Override
            public void onFailure(Call<List<TafelnCall>> call, Throwable t) 
                Toast.makeText(getApplicationContext(), "Fehler beim Laden", Toast.LENGTH_SHORT).show();
            


        );


    
private void handleIntent(Intent intent) 

    if (Intent.ACTION_SEARCH.equals(intent.getAction())) 
        String query = intent.getStringExtra(SearchManager.QUERY);
        //use the query to search your data somehow
    



【问题讨论】:

【参考方案1】:

我将过滤器直接应用到 ListView,而不是适配器......这些是我的覆盖:

public boolean onQueryTextChange(String newText) 
    if (TextUtils.isEmpty(newText)) 
        breedListView.clearTextFilter();
     else 
        breedListView.setFilterText(newText.toString());
    
    return true;


public boolean onQueryTextSubmit(String query) 
    if (TextUtils.isEmpty(query)) 
        breedListView.clearTextFilter();
     else 
        breedListView.setFilterText(query.toString());
    
    return false;

我的breedListView和你的listView一样

final ListView listView = (ListView) findViewById(R.id.listView);
// Here is how you would do it
listView.setFilterText(query.toString());

这里是一些设置

public class DogGuideFragment extends ListFragment
    …
private ListView breedListView;
… 
//In a ListFragment, getListView() gets the main ListView of the Fragment
breedListView = getListView();
breedListView.setFastScrollEnabled(true);
    breedListView.setTextFilterEnabled(true);
…
//setListAdapter is a method of a ListFragment that sets the data for the ListView
setListAdapter(new ArrayAdapter<String>(thisContext,
                        android.R.layout.simple_list_item_1, listOfBreeds));

【讨论】:

感谢您的回答!也许这是我没有直接应用于listView的问题。如何直接申请listview?我不太明白“breedListView”的作用。无法通过谷歌找到任何好的提示。 :(

以上是关于如何在 json 对象的列表视图中搜索?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据 JSON 数据和过滤参数过滤列表视图?

如何在列表视图中显示 json 数据?

在颤动的列表视图中搜索

如何在模板中显示单个 JSON 对象

如何使用REST框架从视图中获取JSON对象

如何将反序列化JSON中的列表传递给视图到选择列表