You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView报错No adapter attached; skipping layout,列表不显示求助

解决RecyclerView报错:E/RecyclerView: No adapter attached; skipping layout 及列表空白问题

我仔细排查了你的代码,找到了几个核心问题,这就是导致你遇到RecyclerView报错、列表空白的关键原因:


1. 最致命的错误:onCreateView返回了null

你的onCreateView方法最后一行写的是return null;,但实际上你已经通过inflater.inflate创建了Fragment的布局View对象v。返回null会直接导致整个Fragment的布局都不会被渲染,RecyclerView自然无法显示出来。

2. 加载歌曲后未正确更新RecyclerView数据

在loadSongs方法里,你重新创建了一个songAdapter1实例,但没有把这个新Adapter绑定到RecyclerView上;而且就算你只是往原有的_songs集合里添加数据,也需要通知Adapter数据更新,否则RecyclerView不会刷新显示新内容。

3. MediaPlayer未初始化存在空指针风险

在Item点击事件中,你直接调用mediaPlayer.isPlaying(),但第一次点击时mediaPlayer还是null状态,会触发空指针异常,导致点击逻辑执行失败。


修正后的完整代码

public class SongsTab extends Fragment { 
    private ArrayList<songInfo> _songs = new ArrayList<>(); 
    RecyclerView recyclerView; 
    SeekBar seekBar; 
    songAdapter songAdapter1; 
    MediaPlayer mediaPlayer; 
    private Handler myHandler = new Handler(); 
    Cursor cursor; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        View v = inflater.inflate(R.layout.songs, container, false); 
        recyclerView = v.findViewById(R.id.recyclerView); 
        seekBar = v.findViewById(R.id.seekBar); 
        // 初始化Adapter并绑定到RecyclerView
        songAdapter1 = new songAdapter(_songs, getContext()); 
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()); 
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), linearLayoutManager.getOrientation()); 
        recyclerView.setLayoutManager(linearLayoutManager); 
        recyclerView.addItemDecoration(dividerItemDecoration); 
        recyclerView.setAdapter(songAdapter1); 

        songAdapter1.setOnitemClickListener(new songAdapter.OnitemClickListener() { 
            @Override 
            public void onItemclick(songAdapter.ViewHolder holder, View v, songInfo obj, int position) { 
                System.gc(); 
                int songPathIndex = cursor.getColumnIndex(MediaStore.Audio.Media.DATA); 
                cursor.moveToPosition(position); 
                final String filename = cursor.getString(songPathIndex); 

                // 先判断mediaPlayer是否为null,避免空指针
                if (mediaPlayer != null && mediaPlayer.isPlaying()) { 
                    mediaPlayer.stop(); 
                    mediaPlayer.reset(); 
                    mediaPlayer.release(); 
                    mediaPlayer = null; 
                } else { 
                    Runnable runnable = new Runnable() { 
                        @Override 
                        public void run() { 
                            try { 
                                mediaPlayer = new MediaPlayer(); 
                                mediaPlayer.setDataSource(filename); 
                                mediaPlayer.prepareAsync(); 
                                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
                                    @Override 
                                    public void onPrepared(MediaPlayer mp) { 
                                        mp.start(); 
                                        seekBar.setProgress(0); 
                                        seekBar.setMax(mediaPlayer.getDuration()); 
                                        Log.d("Prog", "run: " + mediaPlayer.getDuration()); 
                                    } 
                                }); 
                            } catch (Exception e) { 
                                e.printStackTrace(); // 不要吞掉异常,方便后续排查问题
                            } 
                        } 
                    }; 
                    myHandler.postDelayed(runnable, 100); 
                } 
            } 
        }); 

        checkUserPermission(); 
        Thread t = new runThread(); 
        t.start(); 
        // 返回正确的View对象,而不是null
        return v; 
    } 

    public class runThread extends Thread { 
        @Override 
        public void run() { 
            while (true) { 
                try { 
                    Thread.sleep(1000); 
                } catch (InterruptedException e) { 
                    e.printStackTrace(); 
                } 
                Log.d("Runwa", "run: " + 1); 
                // 增加播放状态判断,避免不必要的UI更新
                if (mediaPlayer != null && mediaPlayer.isPlaying()) { 
                    seekBar.post(new Runnable() { 
                        @Override 
                        public void run() { 
                            seekBar.setProgress(mediaPlayer.getCurrentPosition()); 
                        } 
                    }); 
                    Log.d("Runwa", "run: " + mediaPlayer.getCurrentPosition()); 
                } 
            } 
        } 
    } 

    private void checkUserPermission(){ 
        if(Build.VERSION.SDK_INT>=23){ 
            if(ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ 
                requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},123); 
                return; 
            } 
        } 
        loadSongs(); 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
        switch (requestCode){ 
            case 123: 
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED){ 
                    loadSongs(); 
                }else{ 
                    Toast.makeText(getContext(), "Permission Denied", Toast.LENGTH_SHORT).show(); 
                    checkUserPermission(); 
                } 
                break; 
            default: 
                super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
        } 
    } 

    private void loadSongs(){ 
        Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
        String selection = MediaStore.Audio.Media.IS_MUSIC+"!=0"; 
        cursor =getActivity().getContentResolver().query(uri,null,selection,null,null); 
        if(cursor != null){ 
            _songs.clear(); // 先清空旧数据,避免重复加载
            if(cursor.moveToFirst()){ 
                do{ 
                    String name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)); 
                    String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)); 
                    // 修正:存储实际文件路径,而不是列索引
                    String songPath = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)); 
                    songInfo s = new songInfo(name,artist,songPath); 
                    _songs.add(s); 
                }while (cursor.moveToNext()); 
            } 
            cursor.close(); 
            // 不需要重新创建Adapter,直接通知数据更新即可
            songAdapter1.notifyDataSetChanged(); 
        } 
    } 
}

额外说明

  • 我还修正了loadSongs里的一个逻辑错误:你之前把MediaStore.Audio.Media.DATA的列索引存到了songInfo里,这显然不对,应该存储实际的文件路径字符串。
  • 建议不要吞掉异常(比如之前的catch (Exception e) { }),打印异常信息能帮你快速排查后续可能遇到的问题。

内容的提问来源于stack exchange,提问作者devesh kumawat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:58:10