当我打开搜索到的项目时,它打开的是 ListView 的第一项而不是搜索到的项目。即使成功搜索并找到项目

When I opened the searched item, it is opening the first item of ListView not the searched one. Even if search and find the items successfuly

当我打开搜索项时,它打开的是 ListView 的第一项,而不是搜索项。即使搜索并找到项目成功。

我使用“implements Filterable”配置适配器并使用“.setTextFilterEnabled(true)”启用 Listview,但不起作用。

我看到我必须实施“public Filter getFilter()”,但我不知道该怎么做。

当我在 EditText 中键入一些词时,例如“cel”或“12”,过滤器开始运行,但结果始终相同:Listview 中的前两个项目,无论 Listview 中有什么 ( listview的内容是随机的)。

下面是我的 Activity 的片段:

public class MusicActivity extends AppCompatActivity implements SearchView.OnQueryTextListener  {
private boolean checkPermission = false;
ProgressDialog progressDialog;
ListView listView;
List<String> songsNameList;
List<String> songsUrlList;
List<String> songsArtistList;
List<String> songsDurationList;
ListAdapter adapter;
JcPlayerView jcPlayerView;
List<JcAudio> jcAudios;
List<String> thumbnail;

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

    progressDialog = new ProgressDialog(this);
    progressDialog.show();
    progressDialog.setMessage("Please Wait...");
    listView = findViewById(R.id.songsList);
    songsNameList = new ArrayList<>();
    songsUrlList = new ArrayList<>();
    songsArtistList = new ArrayList<>();
    songsDurationList = new ArrayList<>();
    jcAudios = new ArrayList<>();
    thumbnail = new ArrayList<>();
    jcPlayerView = findViewById(R.id.jcplayer);
    retrieveSongs();

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {




            jcPlayerView.playAudio(jcAudios.get(i));
            jcPlayerView.setVisibility(View.VISIBLE);
            jcPlayerView.createNotification();
            adapter.notifyDataSetChanged();
        }
    });


}

// RETRIEVING THE SONGS FROM THE SERVER
public void retrieveSongs() {
    DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Songs");
    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            for (DataSnapshot ds : snapshot.getChildren()) {
                Song song = ds.getValue(Song.class);
                songsNameList.add(song.getSongName());
                songsUrlList.add(song.getSongUrl());
                songsArtistList.add(song.getSongArtist());
                songsDurationList.add(song.getSongDuration());
                thumbnail.add(song.getImageUrl());

                jcAudios.add(JcAudio.createFromURL(song.getSongName(), song.getSongUrl()));
            }
            adapter = new ListAdapter(getApplicationContext(), songsNameList, thumbnail, songsArtistList, songsDurationList);
            jcPlayerView.initPlaylist(jcAudios, null);
            listView.setAdapter(adapter);
            adapter.notifyDataSetChanged();
            progressDialog.dismiss();
        }
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            Toast.makeText(MusicActivity.this, "FAILED!", Toast.LENGTH_SHORT).show();
        }
    });


}






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

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    switch (item.getItemId()){
        case R.id.searchmenu:
            startActivity(new Intent(MusicActivity.this,Search.class));
            break;


        case R.id.requestmenu:

            startActivity(new Intent(MusicActivity.this,UploadSongActivity.class));
            break;

        case R.id.sharemenu:




            break;

    }

    return true;
}*/






// Filter Class






// METHOD TO HANDEL RUNTIME PERMISSIONS
private boolean validatePermissions(){
    Dexter.withContext(getApplicationContext())
            .withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
            .withListener(new PermissionListener() {
                @Override
                public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
                    checkPermission = true;
                }
                @Override
                public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) {
                    checkPermission = false;
                }
                @Override
                public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
                    permissionToken.continuePermissionRequest();
                }
            }).check();
    return checkPermission;

}

@Override
public boolean onQueryTextSubmit(String query) {

    Toast.makeText(this, "Query Inserted", Toast.LENGTH_SHORT).show();
    return true;

}

@Override
public boolean onQueryTextChange(String newText) {

    if(TextUtils.isEmpty(newText)){
        adapter.filter("");
        listView.clearTextFilter();
    }else{
        String texto = newText;
        adapter.filter(newText);
    }
    return true;

}

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

    MenuItem searchItem = menu.findItem(R.id.search);

    SearchView searchView = (SearchView) searchItem.getActionView();
    searchView.setQueryHint("Search Catholic songs");
    searchView.setOnQueryTextListener(this);
    searchView.setIconified(false);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    if (id == R.id.search) {
        return true;
    }

    else if(id == R.id.Rate){
        /*if (mInterstitialAd.isLoaded()) {
            mInterstitialAd.show();
        } else {
            //log.d("TAG", "The intersitial wasn't loaded yet.");
        }*/
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + getString(R.string.packegname)));
        startActivity(intent);
    }
    else if (id ==R.id.sharemenu){

        Intent sendIntent = new Intent();
        sendIntent.setAction(Intent.ACTION_SEND);
        sendIntent.putExtra(Intent.EXTRA_TEXT,
                "Hey ! check out this  music service that gives you access to Hundreds  of catholic  songs. through Catholic app at: https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID);
        sendIntent.setType("text/plain");
        startActivity(sendIntent);


    }
    else  if(id == R.id.uploadItem){

        if (validatePermissions()){
            Intent intent = new Intent(this,UploadSongActivity.class);
            startActivity(intent);
        }

    }

    return super.onOptionsItemSelected(item);
}

在我的 CustomAdapter 以下:

public class ListAdapter extends BaseAdapter  {

List<String> songNames;
List<String> thumbnails;
List<String> songArtist;
List<String> songDuration;
Context context;
private List<String> copyList;
private int searchedItem = -1;
private ArrayList<Song> arraylist;



public ListAdapter(Context context, List<String> songNames, List<String> thumbnails, List<String> songArtist, List<String> songDuration) {
    this.context = context;
    this.songNames = songNames;
    this.thumbnails = thumbnails;
    this.songArtist = songArtist;
    this.songDuration = songDuration;
    copyList = new ArrayList<String>();
    copyList.addAll(songNames);


}

@Override
public int getCount() {
    return songNames.size();
}

@Override
public Object getItem(int i) {
    return songNames.get(i);
}

@Override
public long getItemId(int i) {
    return i;
}

@SuppressLint({"InflateParams", "ViewHolder"})
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
    final ViewHolder viewHolder;
    if (view == null) {
        view = LayoutInflater.from(context).inflate(R.layout.songs_list_layout, null);
        viewHolder = new ViewHolder(view);
        view.setTag(viewHolder);
    }else {
        viewHolder = (ViewHolder) view.getTag();
    }



    Transformation transformation = new RoundedTransformationBuilder()
            .cornerRadiusDp(15)
            .build();

    Picasso.get().load(thumbnails.get(i)).transform(transformation).into(viewHolder.thumbnail);
    viewHolder.songName.setText(songNames.get(i));
    viewHolder.artistName.setText(songArtist.get(i));
    viewHolder.songDuration.setText(songDuration.get(i));
    return view;
}

public void filter(String queryText)

{

    songNames.clear();

    if(queryText.isEmpty())
    {
        songNames.addAll(copyList);
    }
    else
    {

        for(String name: copyList)
        {
            if(name.toLowerCase().contains(queryText.toLowerCase()))
            {
                songNames.add(name);
            }
        }

    }

    notifyDataSetChanged();
}





private static class ViewHolder{
   TextView songName;
    TextView artistName;
    TextView songDuration;
   ImageView thumbnail;
   CardView cardView;
   ImageView currentlyPlaying;

    ViewHolder(View view){
        songName = view.findViewById(R.id.songName);
        thumbnail = view.findViewById(R.id.songThumbnail);
        artistName = view.findViewById(R.id.artistName);
        songDuration = view.findViewById(R.id.songDuration);
        cardView = view.findViewById(R.id.cardView);
        currentlyPlaying = view.findViewById(R.id.currentlyPlaying);
    }
}

缺少什么?

我改进了你的适配器,没有测试它,但它应该工作......我认为转发歌曲列表比单独转发每个字段的列表更容易......你有用于过滤的原始列表和 filteredList对于适配器视图...

已编辑:您必须实施 Filterable,抱歉我没看到这个...

public class ListAdapter extends BaseAdapter implements Filterable {

    private final Context context;
    private final List<Song> songlist;
    private final List<Song> filteredList;

    public ListAdapter(Context context, List<Song> songlist) {
        this.context = context;
        this.songlist = songlist;
        filteredList = new ArrayList<>();
        filteredList.addAll(songlist);
    }

    @Override
    public int getCount() {
        return filteredList.size();
    }

    @Override
    public Object getItem(int i) {
        return filteredList.get(i); // return Song item
    }

    @Override
    public long getItemId(int i) {
        return i;  //TODO change this to return song id
    }

    @SuppressLint({"InflateParams", "ViewHolder"})
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        final ViewHolder viewHolder;
        if (view == null) {
            view = LayoutInflater.from(context).inflate(R.layout.songs_list_layout, null);
            viewHolder = new ViewHolder(view);
            view.setTag(viewHolder);
        }else {
            viewHolder = (ViewHolder) view.getTag();
        }

        Transformation transformation = new RoundedTransformationBuilder()
                .cornerRadiusDp(15)
                .build();

        Song song = filteredList.get(i);

        Picasso.get().load(song.getImageUrl()).transform(transformation).into(viewHolder.thumbnail);
        viewHolder.songName.setText(song.getSongName());
        viewHolder.artistName.setText(song.getSongArtist());
        viewHolder.songDuration.setText(song.getSongDuration());
        return view;
    }

    
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering (CharSequence constraint) {
            FilterResults results = new FilterResults();
            if (songlist != null && constraint != null) {
                filteredList.clear();
                List<Song> newValues = new ArrayList<>();
                for (Song song: songlist) {
                    if(constraint.length() == 0) {
                        newValues.add(song); //TODO change this if you want empty list
                    }else{
                        if(song.getSongName.toLowerCase().contains(constraint.toString().toLowerCase()))  {
                            newValues.add(song);
                        }
                    }
                }
                filteredList.addAll(newValues);
                //filteredList = newValues;
                results.count = newValues.size();
            }
            return results;
        }

        @Override
        protected void publishResults (CharSequence constraint, FilterResults results) {
            if (results != null && results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    };
}



    private static class ViewHolder{
        TextView songName;
        TextView artistName;
        TextView songDuration;
        ImageView thumbnail;
        CardView cardView;
        ImageView currentlyPlaying;

        ViewHolder(View view){
            songName = view.findViewById(R.id.songName);
            thumbnail = view.findViewById(R.id.songThumbnail);
            artistName = view.findViewById(R.id.artistName);
            songDuration = view.findViewById(R.id.songDuration);
            cardView = view.findViewById(R.id.cardView);
            currentlyPlaying = view.findViewById(R.id.currentlyPlaying);
        }
    }
}

public void retrieveSongs() {
        DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Songs");
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                List<Song> songsList = new ArrayList<>();
                for (DataSnapshot ds : snapshot.getChildren()) {
                    Song song = ds.getValue(Song.class);
                    songsList.add(song);
                    jcAudios.add(JcAudio.createFromURL(song.getSongName(), song.getSongUrl()));
                }
                adapter = new ListAdapter(getApplicationContext(), songsList);
                jcPlayerView.initPlaylist(jcAudios, null);
                listView.setAdapter(adapter);
                adapter.notifyDataSetChanged();
                progressDialog.dismiss();
            }
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Toast.makeText(MusicActivity.this, "FAILED!", Toast.LENGTH_SHORT).show();
            }
        }); 
    }

最好在 retrieveSongs 中创建一个适配器和 swapData 实例...

编辑:尝试这样的事情

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            Song song = (Song)adapter.getItem(i)
            jcPlayerView.playAudio(JcAudio.createFromURL(song.getSongName(), song.getSongUrl()));
            jcPlayerView.setVisibility(View.VISIBLE);
            jcPlayerView.createNotification();
            adapter.notifyDataSetChanged();
        }
    });