带有 ArrayAdapter 的 ListView 未在 Android 11 上显示内容

Posted

技术标签:

【中文标题】带有 ArrayAdapter 的 ListView 未在 Android 11 上显示内容【英文标题】:ListView with ArrayAdapter not showing content on Android 11 【发布时间】:2021-08-13 15:48:24 【问题描述】:

在我们的 android 应用程序中,高级设置显示在正常设置下的其自己的列表视图中。默认情况下,仅在事先输入密码时才会填充列表视图。 在我们在 Android 11 上测试该应用程序之前,这一直很好。现在,如果输入密码,列表视图将保持为空。调试表明,连接到列表视图的 ArrayAdapter 确实填充了正确的数据。在 Android 10 或更低版本的设备上进行测试非常好。

任何进一步调试或查阅 android 迁移指南的尝试都没有结果。有人打过吗?

XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:orientation="vertical">
    
    <View
        style="@style/Divider"
        android:background="@color/BlueDark" />

    <ListView
        android:id="@+id/settings_list_view"
        android:layout_
        android:layout_
        android:layout_marginTop="0dp"
        android:divider="@color/Blue"
        android:dividerHeight="1dp"></ListView>

    <View
        style="@style/Divider"
        android:background="@color/Blue" />

    <LinearLayout
        android:layout_
        android:layout_
        android:layout_marginBottom="4dp"
        android:layout_marginTop="0dp"
        android:orientation="vertical">

        <ListView
            android:id="@+id/advanced_settings_list_view"
            android:layout_
            android:layout_
            android:divider="@color/Green"
            android:dividerHeight="1dp">
        </ListView>
    </LinearLayout>

    <View
        style="@style/Divider"
        android:background="@color/BlueDark" />
</LinearLayout>

ArrayAdapter:

public class SettingsListAdapter extends ArrayAdapter<SettingsItemDataModel> 

    // View lookup cache
    private static class ViewHolder 
        TextView txtSettingLabel;
        TextView txtSetting;
    

    Context mContext;

    public SettingsListAdapter(ArrayList<SettingsItemDataModel> data, Context context) 
        super(context, R.layout.row_item, data);
        this.mContext = context;
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        // Get the data item for this position
        SettingsItemDataModel dataModel = getItem(position);
        // Check if an existing view is being reused, otherwise inflate the view
        ViewHolder viewHolder; // view lookup cache stored in tag

        if (convertView == null) 

            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.row_item, parent, false);
            viewHolder.txtSettingLabel = convertView.findViewById(R.id.setting_list_child_label);
            viewHolder.txtSetting = convertView.findViewById(R.id.setting_list_child_setting);

            convertView.setTag(viewHolder);
         else 
            viewHolder = (ViewHolder) convertView.getTag();
        
        viewHolder.txtSettingLabel.setText(dataModel.getSettingPair()[0]);
        viewHolder.txtSetting.setText(dataModel.getSettingPair()[1]);
        // Return the completed view to render on screen
        return convertView;
    

活动(仅相关部分。当用户正确输入密码时会调用 updateAdvancedSettings()):

private ArrayList<SettingsItemDataModel> settings;
private ListView advancedSettingsListView;
private SettingsListAdapter advancedSettingsListAdapter;
private ArrayList<SettingsItemDataModel> advancedSettings = new ArrayList<>();

private void setupListViews(View tabView) 

    settings = new ArrayList<>();

    for (SettingsItemDataModel.Identifier key : SettingsService.getInstance().getSettings().keySet()) 

        SettingsItemDataModel chldData = new SettingsItemDataModel(key, SettingsService.getInstance().getSettings().get(key));

        settings.add(chldData);
    

    ListView settingsListView = tabView.findViewById(R.id.settings_list_view);
    SettingsListAdapter settingsListAdapter = new SettingsListAdapter(settings, context);
    settingsListView.setAdapter(settingsListAdapter);
    settingsListView.setOnItemClickListener((parent, view, position, id) -> 
        if (!isNavigationLocked()) 
            Object object = parent.getItemAtPosition(position);
            SettingsItemDataModel dataModel = (SettingsItemDataModel) object;
            if (SettingsItemDataModel.Identifier.ADV_SETTINGS.equals(dataModel.getSettingsIdentifier())) 
                showAdvancedSettingsDialog();
             else if (SettingsItemDataModel.Identifier.LANGUAGE.equals(dataModel.getSettingsIdentifier())) 
                Intent intent = new Intent(Settings.ACTION_LOCALE_SETTINGS);
                startActivity(intent);
             else if (FASTMODE.equals(dataModel.getSettingsIdentifier())) 
                showInputSettingsRadioDialog(dataModel);
            
        
    );

    advancedSettingsListView = tabView.findViewById(R.id.advanced_settings_list_view);
    advancedSettingsListAdapter = new SettingsListAdapter(advancedSettings, context);
    advancedSettingsListView.setAdapter(advancedSettingsListAdapter);
    advancedSettingsListView.setOnItemClickListener((parent, view, position, id) -> 
        if (!isNavigationLocked()) 
            Object object = parent.getItemAtPosition(position);
            SettingsItemDataModel dataModel = (SettingsItemDataModel) object;

            if (DEL_ALL_MAILS.equals(dataModel.getSettingsIdentifier())) 
                showSimpleSettingsDialog(dataModel);
             else if (IMG_FILE_TYPE.equals(dataModel.getSettingsIdentifier())) 
                showInputSettingsRadioDialog(dataModel);
             else if (IMG_COMP_LEV.equals(dataModel.getSettingsIdentifier())) 
                showInputSettingsSeekBarDialog(dataModel);
             else if (SWIPE.equals(dataModel.getSettingsIdentifier())) 
                showInputSettingsRadioDialog(dataModel);
             else if (ZIP_COMP_TYPE.equals(dataModel.getSettingsIdentifier())) 
                showInputSettingsRadioDialog(dataModel);
             else if (ZIP_COMP_LEV.equals(dataModel.getSettingsIdentifier())) 
                showInputSettingsSpinnerDialog(dataModel);
             else 
                showInputSettingsDialog(dataModel);
            
        
    );
    settingsListView.invalidate();
    advancedSettingsListView.invalidate();


public void updateAdvancedSettings() 

    advancedSettings.clear();

    LinkedHashMap<SettingsItemDataModel.Identifier, String[]> advSettingData = null;
    advSettingData = SettingsService.getInstance().getAdvancedSettings();

    for (SettingsItemDataModel.Identifier key : advSettingData.keySet()) 

        SettingsItemDataModel chldData = new SettingsItemDataModel(key, advSettingData.get(key));

        advancedSettings.add(chldData);
    
    try 
        SettingsService.getInstance().saveExtAdvancedSetting();
     catch (IOException e) 
        e.printStackTrace();
    

【问题讨论】:

【参考方案1】:

答案很简单。我得打电话

advancedSettingsListAdapter.notifyDataSetChanged();

在我填充适配器后手动操作。无论出于何种原因,这似乎都是在以前版本的操作系统中自动完成的。

【讨论】:

它在我的情况下不起作用

以上是关于带有 ArrayAdapter 的 ListView 未在 Android 11 上显示内容的主要内容,如果未能解决你的问题,请参考以下文章

更新 ListView 中的特定项目

Android ArrayAdapter.Add 方法不起作用

Listview ArrayAdapter 自定义项 onClickListener 仅第一次工作

如何修复此 ArrayAdapter 需要资源 ID 为 TextView

当用户旋转手机并将所有数据保留在 ArrayAdapter 中时,保留列表视图项的良好解决方案

java 为listvie实现基础适配器