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

TabLayout切换时RecyclerView内容刷新异常问题排查

Tab切换回第一个Tab时RecyclerView内容不更新的问题修复

我仔细看了你的代码,很快就找到了导致问题的核心原因,还有几个可以优化的点,一起来解决:

核心问题:Switch Case缺少Break语句

你的TabLayout选中监听里的switch代码块,case 0后面没有添加break!这会导致选中第一个Tab(position=0)时,代码执行完refreshList("/sdcard/")后,会继续往下执行case 1的refreshList("/storage/0000-0000/")——相当于最后还是加载了第二个Tab的路径内容,所以你看起来第一个Tab的内容没变化,实际上是被后续代码覆盖了。

修复后的Tab监听代码

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        System.out.println(tab.getPosition());
        switch(tab.getPosition()){
            case 0:
                refreshList("/sdcard/");
                break; // 必须添加这个break,终止当前case的执行
            case 1:
                refreshList("/storage/0000-0000/");
                break; // 这里也建议加上,养成良好编码习惯
        }
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {}

    @Override
    public void onTabReselected(TabLayout.Tab tab) {}
});

额外优化建议(提升代码稳定性与性能)

1. 处理权限申请后的回调

你现在申请了存储权限,但没有处理权限申请结果的回调。当用户授予权限后,需要重新调用refreshList,否则第一次打开App如果用户刚授权,列表不会加载。在Fragment中添加以下代码:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 权限授予成功,刷新当前选中Tab的列表
            TabLayout.Tab selectedTab = tabLayout.getSelectedTab();
            if (selectedTab != null) {
                switch(selectedTab.getPosition()){
                    case 0:
                        refreshList("/sdcard/");
                        break;
                    case 1:
                        refreshList("/storage/0000-0000/");
                        break;
                }
            }
        } else {
            // 提示用户需要权限才能查看文件
            Snackbar.make(view, "需要存储权限才能访问文件", Snackbar.LENGTH_LONG).show();
        }
    }
}

2. 复用RecyclerView Adapter,避免频繁创建实例

每次调用refreshList都创建新的OwnAdapter实例会浪费资源,建议复用已有Adapter,更新数据集后通知刷新:

修改OwnAdapter,添加数据更新方法

public class OwnAdapter extends RecyclerView.Adapter<OwnAdapter.MyViewHolder> {
    private String[] dataset;

    public static class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView textView;
        public MyViewHolder(TextView v) {
            super(v);
            textView = v;
        }
    }

    public OwnAdapter(String[] myDataset) {
        dataset = myDataset;
    }

    // 添加更新数据集的方法
    public void updateData(String[] newDataset) {
        dataset = newDataset;
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        TextView v = (TextView) LayoutInflater.from(parent.getContext())
                .inflate(R.layout.textview_for_files, parent, false);
        return new MyViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.textView.setText(dataset[position]);
    }

    @Override
    public int getItemCount() {
        return dataset.length;
    }
}

修改refreshList方法,复用Adapter

private void refreshList(String s){
    File file = new File(s);
    File[] files = file.listFiles();
    ArrayList<File> itemArrayList = new ArrayList<>();
    
    // 防止files为null导致空指针异常
    if (files != null) {
        for (File f : files) {
            itemArrayList.add(f.isFile() ? f : f.getAbsoluteFile());
        }
    }

    String[] itemNames = new String[itemArrayList.size()];
    for(int j = 0; j < itemNames.length; j++){
        itemNames[j] = itemArrayList.get(j).getName();
    }

    if (ownAdapter == null) {
        ownAdapter = new OwnAdapter(itemNames);
        recView.setAdapter(ownAdapter);
    } else {
        ownAdapter.updateData(itemNames);
    }
}

3. 空指针防护

file.listFiles()可能返回null(比如路径不存在、权限不足),所以一定要先判断files != null再遍历,避免抛出RuntimeException。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:12:17