自定义对话框片段内的自定义对象列表的微调器无效

时间:2017-11-02 13:38:09

标签: android android-fragments dialog android-spinner

我在这里结束了我的智慧。我一直在研究这个android视图,我想使用一个对话框让用户填写一个表单(本质上)。表单包含两个列表项(我想使用两个微调器显示)。将根据列表1中的所选项目填充第二个列表的内容。 一旦两个Spinners都选择了一个项目,我就会使用Recycler视图来显示要填充的其他字段。这些字段将根据列表2中选择的项目决定。

我目前的困境是我无法通过对话框向我显示第一个项目列表。提示时,对话框和其中的微调器呈现正常。但是旋转器总是空着的。

这是我的代码。我将从spinner.xml布局的标记开始:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="10dp"
        android:textSize="14sp"
        android:textColor="@android:color/black"/>
</LinearLayout>

我的自定义对话框的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/properties_ll"
    android:background="@color/translucent_green">
    <Spinner
        android:layout_width="120dp"
        android:layout_height="40dp"
        android:clickable="true"
        android:id="@+id/material_types_dd"
        android:spinnerMode="dropdown"/>
    <Spinner
        android:layout_width="120dp"
        android:layout_height="40dp"
        android:clickable="true"
        android:id="@+id/materials_dd"
        android:spinnerMode="dropdown"/>
    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/material_detials_rv"/>
</LinearLayout>

自定义对话框类(使用Volley的所有HTTP调用都在运行并经过全面测试,所以我知道问题不存在):

public class TacDetailsDialogFragment extends DialogFragment {

    private static final String TAG = TacDetailsDialogFragment.class.getSimpleName();


    @BindView(R.id.properties_ll)
    LinearLayout properties;

    @BindView(R.id.material_types_dd)
    Spinner materialtypesDD;

    @BindView(R.id.materials_dd)
    Spinner materialsdd;

    @BindView(R.id.material_detials_rv)
    RecyclerView materialDetailsRecycler;

    private List<BaseModel> materials;
    private List<BaseModel> materialTypes;
    private BaseModel selectedMaterial;
    private BaseModel selectedMaterialType;
    private List<BaseModel> selectedMaterialFields;
    private List<List<BaseModel>> selectedMaterialFieldUnits;

    ProgressBarHelper progressBarHelper;

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();

        builder.setView(inflater.inflate(R.layout.tac_details_dialog, null))
                .setPositiveButton(
                    R.string.ok,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    }
                )
                .setNegativeButton(
                    "Cancel",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            TacDetailsDialogFragment.this.getDialog().cancel();
                        }
                    }
                );
        View view = inflater.inflate(R.layout.tac_details_dialog, null);
        ButterKnife.bind(this, view);

        progressBarHelper = new ProgressBarHelper(this.getActivity());
        getMaterialTypes();
        materialtypesDD.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Log.d(TAG, materialTypes.get(position).toString());
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

//        materialsdd.setOnItemSelectedListener(new ClickToSelectEditText.OnItemSelectedListener() {
//            @Override
//            public void onItemSelectedListener(Object item, int selectedIndex) {
//                getMaterialFields();
//            }
//        });


        return builder.create();
    }

    /* The activity that creates an instance of this dialog must implement
     * this interface in order to receive event callbacks. Each method
     * passes the dialogfrag in case the host needs to query it */
    public interface TacDetailsDialogListener {
        public void onDialogPositiveClick(DialogFragment dialog);
    }

    TacDetailsDialogListener mListener;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try{
            mListener = (TacDetailsDialogListener) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString() + " must implement TacDetailsDialogListener");
        }
    }

    private void initMaterialTypesDD() {
        materialtypesDD.setAdapter(new ArrayAdapter<BaseModel>(getContext(), R.layout.spinner, materialTypes) {
            @Override
            public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                View view = super.getDropDownView(position, convertView, parent);

//                TextView text = (TextView) view.findViewById(R.id.text1);
//                text.setVisibility(View.VISIBLE);
//                text.setTextColor(Color.BLACK);

                return view;
            }
        });
    }


    private void initMaterialsDD() {
        materialsdd.setAdapter(new ArrayAdapter<>(getContext(), R.layout.support_simple_spinner_dropdown_item, materials));
    }

    private void initMaterialFields() {
        materialDetailsRecycler.setLayoutManager(new LinearLayoutManager(this.getContext(), LinearLayoutManager.VERTICAL, false));
        materialDetailsRecycler.setAdapter(new MaterialDetailRecyclerViewAdapter(selectedMaterialFields, selectedMaterialFieldUnits));
    }

    private void initMaterialTypes(JSONArray data) throws JSONException {
        materialTypes = new ArrayList<BaseModel>();
        for (int i = 0; i < data.length(); i++) {
            materialTypes.add(new BaseModel(data.getJSONObject(i)));
        }
    }

    public void initMaterials(JSONArray data) throws JSONException {
        materials = new ArrayList<BaseModel>();
        for (int i = 0; i < data.length(); i++) {
            materials.add(new BaseModel(data.getJSONObject(i)));
        }
    }


    public void initSelectedMaterialFields(JSONArray data) throws JSONException {
        selectedMaterialFields = new ArrayList<BaseModel>();
        selectedMaterialFieldUnits = new ArrayList<List<BaseModel>>();
        for (int i = 0; i < data.length(); i++) {
            JSONObject field = data.getJSONObject(i);
            selectedMaterialFields.add(new BaseModel(field));

            JSONArray fieldUnits = field.getJSONArray("units");
            List<BaseModel> units = new ArrayList<>();
            for (int j = 0; j < fieldUnits.length(); j++) {
                units.add(new BaseModel(fieldUnits.getJSONObject(j)));
            }
            selectedMaterialFieldUnits.add(units);
        }
    }

    private void getMaterialTypes() {
        VolleySingleton.getInstance(this.getContext()).addToRequestQueue(
                new JsonObjectRequest(
                        Request.Method.GET,
                        getString(R.string.server_ip) + getString(R.string.materialtypes),
                        null,
                        new Response.Listener<JSONObject>() {
                            @Override
                            public void onResponse(JSONObject response) {
                                try {
                                    if (response.getInt("code") == 200) {
                                        initMaterialTypes(response.getJSONArray("data"));
                                        initMaterialTypesDD();
                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }

                            }
                        },
                        new Response.ErrorListener() {
                            @Override
                            public void onErrorResponse(VolleyError error) {
                                error.printStackTrace();
                            }
                        }
                )
        );
    }

    private void getMaterials() {
        VolleySingleton.getInstance(this.getContext()).addToRequestQueue(
                new JsonObjectRequest(
                        Request.Method.GET,
                        getActivity().getString(R.string.server_ip) + getActivity().getString(R.string.materials) + selectedMaterialType.getId(),
                        null,
                        new Response.Listener<JSONObject>() {
                            @Override
                            public void onResponse(JSONObject response) {
                                try {
                                    if (response.getInt("code") == 200) {
                                        JSONArray data = response.getJSONArray("data");
                                        initMaterials(data);
                                        initMaterialsDD();
                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        },
                        new Response.ErrorListener() {
                            @Override
                            public void onErrorResponse(VolleyError error) {

                            }
                        }
                )
        );
    }
    private void getMaterialFields() {
        VolleySingleton.getInstance(this.getContext()).addToRequestQueue(
                new JsonObjectRequest(
                        Request.Method.GET,
                        getString(R.string.server_ip) + getString(R.string.materialfields) + selectedMaterial.getId(),
                        null,
                        new Response.Listener<JSONObject>() {
                            @Override
                            public void onResponse(JSONObject response) {
                                try {
                                    if (response.getInt("code") == 200) {
                                        initSelectedMaterialFields(response.getJSONArray("data"));
                                        initMaterialFields();
                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        },
                        new Response.ErrorListener() {
                            @Override
                            public void onErrorResponse(VolleyError error) {

                            }
                        }
                )
        );
    }
}

自定义对象BaseModel:

public class BaseModel implements Listable {
    String name;
    int id;
    int type_id;

    public BaseModel() {}

    public BaseModel(JSONObject jsonObject) {
        try {
            this.name = jsonObject.getString("name");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        try {
            this.id = jsonObject.getInt("id");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        try {
            this.type_id = jsonObject.getInt("type_id");
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public BaseModel(String name) {
        this.name = name;
    }

    public BaseModel(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public BaseModel(String name, int id, int type_id) {
        this.name = name;
        this.id = id;
        this.type_id = type_id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getType_id() {
        return type_id;
    }

    public void setType_id(int type_id) {
        this.type_id = type_id;
    }

    public String toString() {
        return this.name;
    }

    @Override
    public String getLabel() {
        return this.name;
    }

    @Override
    public void setValues(String name, int id) {
        this.name = name;
        this.id = id;
    }
}

这就是我从主要活动中调用对话框的方式:

public void makeTacDetailsAlert() {
        dialog = new TacDetailsDialogFragment();
        dialog.show(this.getSupportFragmentManager(), "TacDetailsDialogFragment");
    }

Idk如果RecyclerView位是相关的,那么不要将它们包括在这个代码混乱的问题中。

对你来说,S / O众神。

1 个答案:

答案 0 :(得分:0)

感谢一夜好眠,一些更清晰的头脑思考,以及@Sam的回答(https://stackoverflow.com/a/14676975/3438497)我已经解决了我的问题。

除了确保我将对话框和单个视图绑定到同一个布局实例(而不是不同的实例)之外,我还需要按照此处的建议为BaseModel对象创建自定义SpinnerAdapter:https://stackoverflow.com/a/8116756/3438497

希望这有助于解决此问题的任何其他人。