DialogFragment中的ListView在Android 4.0中被禁用

DialogFragment中的ListView在Android 4.0中被禁用,android,dialogfragment,Android,Dialogfragment,我制作了一个自定义对话框片段,用于从后端选择用户。用户是异步加载的,因此我无法使用AlertDialog.Builder.setItems(),因为已经调用了onCreateDialog 因此,我使用一个带有ListView和ProgressBar的自定义布局。 加载数据(并且隐藏progressbar)后,ListView变为可见,适配器被设置,监听器被设置 在另一台安卓5设备上没有问题,但在我的Transformer TF101 testdevice安卓4.0.3上,我无法按下任何项目 奇怪

我制作了一个自定义对话框片段,用于从后端选择用户。用户是异步加载的,因此我无法使用
AlertDialog.Builder.setItems()
,因为已经调用了
onCreateDialog

因此,我使用一个带有ListView和ProgressBar的自定义布局。 加载数据(并且隐藏progressbar)后,ListView变为可见,适配器被设置,监听器被设置

在另一台安卓5设备上没有问题,但在我的Transformer TF101 testdevice安卓4.0.3上,我无法按下任何项目

奇怪的是,当我切换应用程序并返回到我的应用程序时,ListView已启用,现在我可以选择一些内容

布局的XML:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true">

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/listview_gebruikers"
    android:layout_gravity="center_horizontal"
    />

<ProgressBar
    style="?android:attr/progressBarStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progress_gebruikers"
    android:layout_gravity="center" />
</FrameLayout>

对话框片段:

public static final String TAG = OverdragenDialogFragment.class.getSimpleName();

private static final String ARG_OVEREENKOMST = "arg_overeenkomst";
private static final String ARG_ACCOUNT_NAME = "arg_account_name";

private static final String STATE_ACCOUNT_NAME = "state_account_name";
private static final String STATE_OVEREENKOMST = "state_overeenkomst";

private OverdragenCallbacks mListener;

private ListView mListView;
private ProgressBar mProgressBar;


private Overeenkomst mOvereenkomst;
private String mAccountName;

/**
 * A handler object, used for deferring UI operations.
 */
protected Handler mHandler = new Handler();


/**
 * Create a new ChangeStatusDialogFragment
 * @return
 */
public static OverdragenDialogFragment newInstance(String accountName, Overeenkomst overeenkomst) {
    Bundle arguments = new Bundle();
    arguments.putString(ARG_ACCOUNT_NAME, accountName);
    arguments.putSerializable(ARG_OVEREENKOMST, overeenkomst);


    OverdragenDialogFragment fragment = new OverdragenDialogFragment();
    fragment.setArguments(arguments);
    return fragment;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); //getActivity().getLayoutInflater();
    View parent = inflater.inflate(R.layout.dialog_gebruikers, null);

    if(savedInstanceState != null){
        mOvereenkomst = (Overeenkomst) savedInstanceState.getSerializable(STATE_OVEREENKOMST);
        mAccountName = savedInstanceState.getString(STATE_ACCOUNT_NAME);
    }else{
        mOvereenkomst = (Overeenkomst) getArguments().getSerializable(ARG_OVEREENKOMST);
        mAccountName = getArguments().getString(ARG_ACCOUNT_NAME);
    }

    initViews(parent);

    final Loader<List<GebruikerWrapper>> loader = getLoaderManager().getLoader(LoaderIds.API_GEBRUIKERS);
    if(loader != null){
        if(!loader.isStarted()) {
            loader.reset();
            loader.startLoading();
        }
    }else {
        getLoaderManager().initLoader(LoaderIds.API_GEBRUIKERS, null, new LoaderManager.LoaderCallbacks<List<GebruikerWrapper>>() {
            @Override
            public Loader<List<GebruikerWrapper>> onCreateLoader(int id, Bundle args) {
                mProgressBar.setVisibility(View.VISIBLE);
                return new GetGebruikersLoader(getActivity(), mAccountName);
            }


            @Override
            public void onLoadFinished(Loader<List<GebruikerWrapper>> loader, List<GebruikerWrapper> data) {
                mProgressBar.setVisibility(View.GONE);
                if (data == null) {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getActivity(), "Kan de verkopers niet ophalen...", Toast.LENGTH_SHORT).show(); //TODO fatsoenlijke foutmelding
                            dismiss();
                        }
                    });
                }
                mListView.setAdapter(new GebruikerArrayAdapter(getActivity(), data));
                mListView.setOnItemClickListener(OverdragenDialogFragment.this);
                mListView.requestFocus();
            }

            @Override
            public void onLoaderReset(Loader<List<GebruikerWrapper>> loader) {

            }
        });
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle(R.string.title_overdragen)
            .setView(parent);
    return builder.create();
}

private void initViews(View parent) {
    mListView = findView(parent, R.id.listview_gebruikers);
    mProgressBar = findView(parent, R.id.progress_gebruikers);
}

@SuppressWarnings("unchecked")
public <T extends View> T findView(View parent, int id) {
    return (T) parent.findViewById(id);
}


@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString(STATE_ACCOUNT_NAME, mAccountName);
    outState.putSerializable(STATE_OVEREENKOMST, mOvereenkomst);
}

public OverdragenDialogFragment setListener(OverdragenCallbacks mListener) {
    this.mListener = mListener;
    return this;
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    //[..] not relevant [..]        
}
public static final String TAG=overdagendialogfragment.class.getSimpleName();
私有静态最终字符串ARG_OVEREENKOMST=“ARG_OVEREENKOMST”;
私有静态最终字符串ARG\u ACCOUNT\u NAME=“ARG\u ACCOUNT\u NAME”;
私有静态最终字符串STATE\u ACCOUNT\u NAME=“STATE\u ACCOUNT\u NAME”;
私有静态最终字符串状态\u OVEREENKOMST=“STATE\u OVEREENKOMST”;
私人透支代理回调mListener;
私有列表视图;
私人ProgressBar mProgressBar;
私营企业过度经营;
私有字符串mAccountName;
/**
*处理程序对象,用于延迟UI操作。
*/
受保护的处理程序mHandler=新处理程序();
/**
*创建一个新的ChangeStatusDialogFragment
*@返回
*/
public static overdagendialogfragment newInstance(字符串accountName,Overeenkomst-Overeenkomst){
Bundle参数=新Bundle();
arguments.putString(ARG\u ACCOUNT\u NAME,accountName);
参数。可串行化(ARG_OVEREENKOMST,OVEREENKOMST);
OverdagenDialogFragment=新的OverdagenDialogFragment();
fragment.setArguments(参数);
返回片段;
}
@凌驾
创建对话框上的公共对话框(Bundle savedInstanceState){
LayoutFlater充气器=(LayoutFlater)getActivity().getSystemService(Context.LAYOUT_充气器_服务);//getActivity().GetLayoutFlater();
视图父项=充气机。充气(R.layout.dialog\u gebruikers,null);
如果(savedInstanceState!=null){
mOvereenkomst=(Overeenkomst)savedInstanceState.getSerializable(STATE_Overeenkomst);
mAccountName=savedInstanceState.getString(状态\帐户\名称);
}否则{
mOvereenkomst=(Overeenkomst)getArguments().getSerializable(ARG_Overeenkomst);
mAccountName=getArguments().getString(参数帐户名称);
}
初始视图(父级);
最终加载程序Loader=getLoaderManager().getLoader(loaderId.API_GEBRUIKERS);
if(加载程序!=null){
如果(!loader.isStarted()){
loader.reset();
装载机。惊人的装载();
}
}否则{
getLoaderManager().initLoader(LoaderId.API_GEBRUIKERS,null,新LoaderManager.LoaderCallbacks(){
@凌驾
公共加载器onCreateLoader(int-id,Bundle-args){
mProgressBar.setVisibility(View.VISIBLE);
返回新的GetGebruikersLoader(getActivity(),mAccountName);
}
@凌驾
public void onLoadFinished(加载程序,列表数据){
mProgressBar.setVisibility(View.GONE);
如果(数据==null){
mHandler.post(新Runnable(){
@凌驾
公开募捐{
Toast.makeText(getActivity(),“Kan de verkopers niet ophalen…”,Toast.LENGTH_SHORT.show();//TODO fatsoenlijke foutmelding
解雇();
}
});
}
setAdapter(新的GebruikerArrayAdapter(getActivity(),data));
setOnItemClickListener(overdagenDialogFragment.this);
mListView.requestFocus();
}
@凌驾
公共void onLoaderReset(加载器){
}
});
}
AlertDialog.Builder=新建AlertDialog.Builder(getActivity());
builder.setTitle(R.string.title\u overdagen)
.setView(父级);
返回builder.create();
}
私有视图(视图父视图){
mListView=findView(父级,R.id.listview\u gebruikers);
mProgressBar=findView(父级,R.id.progress\u gebruikers);
}
@抑制警告(“未选中”)
公共T findView(视图父级,内部id){
return(T)parent.findViewById(id);
}
@凌驾
SaveInstanceState上的公共无效(束超出状态){
super.onSaveInstanceState(超出状态);
outState.putString(STATE\u ACCOUNT\u NAME,mAccountName);
超出状态。可串行化(STATE_OVEREENKOMST,mOvereenkomst);
}
公共OverdagenDialogFragment setListener(OverdagenCallbacks MLListener){
this.mListener=mListener;
归还这个;
}
@凌驾
public void onItemClick(AdapterView父对象、视图、整型位置、长id){
//[…]不相关[…]
}

听起来像是焦点问题。某些视图正在从您的ListView中窃取焦点,它变得不可触摸。您可以尝试使用类似的代码在活动中调试:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        Log.e(TAG, "Activity gained focus: " + getCurrentFocus());
    } else {
        Log.e(TAG, "Activity lost focus");
        try {
            Log.e(TAG, "Dialog window focused on: " +
                    dialogFragment.getDialog().getWindow().getCurrentFocus());
        } catch (NullPointerException e) {
            Log.i(TAG, "NPE", e);
        }
    }
}
同样,这也不需要:
mListView.requestFocus()

如中所述,您可以使用
AlertDialog.Builder.setAdapter
而不是
AlertDialog.Builder.setItems
来使用动态数据支持列表(它特别提到来自
加载程序的数据)

为了简单起见,以下示例使用
处理程序
在启动5秒后填充列表,而不是
加载程序
。在我运行安卓4.4.4的设备上运行效果非常好

public class ListDialogFragment extends DialogFragment implements DialogInterface.OnClickListener {

    ArrayAdapter<String> arrayAdapter;
    List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                arrayAdapter.addAll(places);
            }
        }, 5000);

        arrayAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1);
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Test List").setAdapter(arrayAdapter, this);
        return builder.create();
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        Log.d(getClass().getSimpleName(), String.format("User clicked item at index %d", which));
    }

}
公共类ListDialogFragment扩展DialogFragment实现DialogInterface.OnClickListener{
ArrayAdapter ArrayAdapter;
List places=Arrays.asList(“布宜诺斯艾利斯”、“科尔多瓦”、“拉普拉塔”);
@凌驾
创建对话框上的公共对话框(Bundle savedInstanceState){
哈