Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何通过android中的片段使用recycler adapter从设备中检索歌曲列表_Android_Android Fragments_Android Recyclerview_Android Contentresolver - Fatal编程技术网

如何通过android中的片段使用recycler adapter从设备中检索歌曲列表

如何通过android中的片段使用recycler adapter从设备中检索歌曲列表,android,android-fragments,android-recyclerview,android-contentresolver,Android,Android Fragments,Android Recyclerview,Android Contentresolver,我想使用recycler adapter over Song Fragment检索设备上的歌曲列表。实现用于检索歌曲列表的内容解析器出错。 请帮忙 这就是我所做的 我已经创建了歌曲模型 从主要活动中扩展了3个片段(下面是歌曲片段之一) 我的歌曲片段 public class TabSong extends Fragment { RecyclerView recyclerView; RecyclerAdapter adapter; @Override public View onCreate

我想使用recycler adapter over Song Fragment检索设备上的歌曲列表。实现用于检索歌曲列表的内容解析器出错。 请帮忙

这就是我所做的

  • 我已经创建了歌曲模型
  • 从主要活动中扩展了3个片段(下面是歌曲片段之一)
我的歌曲片段

public class TabSong extends Fragment {
RecyclerView recyclerView;
RecyclerAdapter adapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Get the view from fragmenttab1.xml
    View v = inflater.inflate(R.layout.tab_song, container, false);
    recyclerView = (RecyclerView) v.findViewById(R.id.recycler_view);

    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(mLayoutManager);

    adapter = new RecyclerAdapter();
    SongList();
    recyclerView.setAdapter(adapter);

    return v;
}

public void SongList() {
    String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
    String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";

    ContentResolver cr = getActivity().getContentResolver();
    String[] projection = {
            MediaStore.Audio.Media._ID,
            MediaStore.Audio.Media.ARTIST,
            MediaStore.Audio.Media.TITLE,
            MediaStore.Audio.Media.DATA,
            MediaStore.Audio.Media.DISPLAY_NAME,
            MediaStore.Audio.Media.DURATION
    };

    Cursor cur = cr.query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            projection,
            selection,
            null,
            sortOrder);

    RecyclerAdapter.songs = new ArrayList<>();
    while (cur.moveToNext()) {
        HashMap<String, String> map = new HashMap<>();
  /*  songs.add(cur.getString(0) + "||"
            + cur.getString(1) + "||"
            + cur.getString(2) + "||"
            + cur.getString(3) + "||"
            + cur.getString(4) + "||" );*/

        map.put("ID", cur.getString(0));
        map.put("artist", cur.getString(1));
        map.put("title", cur.getString(2));
        map.put("displayname", cur.getString(3));
        map.put("duration", cur.getString(4));

        RecyclerAdapter.songs.add(map);
    }
}}
public类TabSong扩展片段{
回收视图回收视图;
回收适配器;
@凌驾
创建视图上的公共视图(布局、充气机、视图组容器、,
Bundle savedInstanceState){
//从fragmenttab1.xml获取视图
视图v=充气机。充气(R.layout.tab_song,容器,假);
recyclerView=(recyclerView)v.findViewById(R.id.recycler\u视图);
RecyclerView.LayoutManager mLayoutManager=新的LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
适配器=新的RecyclerAdapter();
歌曲列表();
recyclerView.setAdapter(适配器);
返回v;
}
公开歌曲列表(){
字符串选择=MediaStore.Audio.Media.IS_MUSIC+“!=0”;
字符串排序器=MediaStore.Audio.Media.TITLE+“ASC”;
ContentResolver cr=getActivity().getContentResolver();
字符串[]投影={
MediaStore.Audio.Media.\u ID,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DISPLAY\u名称,
MediaStore.Audio.Media.DURATION
};
游标cur=cr.query(
MediaStore.Audio.Media.EXTERNAL\u CONTENT\u URI,
投影,
选择,
无效的
分拣机);
RecyclerAdapter.songs=新建ArrayList();
while(cur.moveToNext()){
HashMap=newHashMap();
/*songs.add(cur.getString(0)+“| |”
+cur.getString(1)+“| |”
+cur.getString(2)+“| |”
+cur.getString(3)+“| |”
+cur.getString(4)+“| |””*/
map.put(“ID”,cur.getString(0));
map.put(“艺术家”,cur.getString(1));
map.put(“title”,cur.getString(2));
map.put(“displayname”,cur.getString(3));
map.put(“duration”,cur.getString(4));
RecyclerAdapter.songs.add(地图);
}
}}
我的回收适配器

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder>{ 

static ArrayList<HashMap<String, String>> songs = new ArrayList<>();

@Override
public RecyclerAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.song_list, parent, false);
    MyViewHolder holder = new MyViewHolder(view);
    return holder;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    holder.title.setText(songs.get(position).get("displayname"));
    holder.artist.setText(songs.get(position).get("artist"));
    holder.duration.setText(songs.get(position).get("duration"));
}

@Override
public int getItemCount() {
    return songs.size();
}

public class MyViewHolder extends RecyclerView.ViewHolder{
    public TextView title,duration,artist;

    public MyViewHolder(View view) {
        super(view);
        title = (TextView) view.findViewById(R.id.list_title);
        artist = (TextView) view.findViewById(R.id.list_artist);
        duration = (TextView) view.findViewById(R.id.list_duration);
    }
}}
公共类RecyclerAdapter扩展了RecyclerView.Adapter{ 静态ArrayList歌曲=新建ArrayList(); @凌驾 public RecyclerAdapter.MyViewHolder onCreateViewHolder(视图组父级,int-viewType){ View-View=LayoutInflater.from(parent.getContext()).flate(R.layout.song_list,parent,false); MyViewHolder=新的MyViewHolder(视图); 报税表持有人; } @凌驾 公共无效onBindViewHolder(MyViewHolder,int位置){ holder.title.setText(songs.get(position.get)(“displayname”); holder.artist.setText(songs.get(position.get(“艺术家”)); holder.duration.setText(songs.get(position.get(“duration”)); } @凌驾 public int getItemCount(){ 返回歌曲。大小(); } 公共类MyViewHolder扩展了RecyclerView.ViewHolder{ 公共文本视图标题、持续时间、艺术家; 公共MyViewHolder(视图){ 超级(视图); title=(TextView)view.findViewById(R.id.list\u title); artist=(TextView)view.findViewById(R.id.list\u artist); duration=(TextView)view.findViewById(R.id.list\u duration); } }} #1:不要使用静态成员在适配器中存储歌曲。您所需要的只是某个类的
列表
,您可以定义该类来保存所有歌曲数据

public class Song {
    String displayName;
    String artist;
    // etc.
}
在适配器中创建一个方法,以便在加载新的
列表时交换它。说到这里

#2:您应该使用
加载程序来加载歌曲。有关于装载机的指南。现在的做法是在UI线程上查询MediaProvider,并在UI线程上处理结果,这是错误的。此外,
Loader
s可以在数据更改时自动重新加载,这意味着您无需手动刷新

您可以使用基本的
游标加载程序
启动,尽管您仍将在
onLoadFinished()
内的主线程上处理结果。如果您想做得更好,可以制作一个定制的
加载程序
,该加载程序执行查询并在后台处理结果,然后发布最终的数据结构

另外,确保在使用完
光标后将其关闭


#3:添加、删除或更改支持适配器的项目后,您需要调用适配器上的
notify…
方法之一(请参阅文档开头),以便
RecyclerView
显示更新的数据。

谢谢@Karakuri。1个重要问题,你能简单解释一下吗。如何将所有(歌曲片段、回收器适配器、加载器和模型)连接到仅存在onCreate方法的主活动。在上面提到的类中,我应该在哪里声明和实例化Hashmap数组列表。我不会使用
Hashmap
s的列表。如果要从
光标
中提取数据,请将其提取到具有直接访问权限的内容中,如上面的
歌曲
模型类示例。您的适配器可以有一个通过方法调用设置的
列表
。该活动应获取
RecyclerView
,初始化适配器,并在
onCreate()
中启动加载程序。您将在传递给
initLoader()
LoaderCallbacks
onLoadFinished()
中获取加载的数据。在那里,您将转换为歌曲列表并将其传递给适配器,适配器将替换其列表并执行通知。