【问题标题】:Spinner not working in custom Dialog - why?Spinner 在自定义对话框中不起作用 - 为什么?
【发布时间】:2018-12-13 20:47:04
【问题描述】:

我正在尝试在自定义对话框中使用 android Spinner,但是当我点击 Spinner 时,会打开包含项目的列表,您可以点击它们并关闭视图,但没有选择任何项目。当我在普通片段中使用完全相同的代码时,它可以正常工作。

由于我在任何地方都没有发现任何有用的东西,所以在 Dialog 中使用微调器时有什么需要知道的吗?

CustomDialog 类:

public SelectionDialog(Activity context, ArrayAdapter<T> arrayAdapter, List<T> objects) {
    super(context);
    this.activity = context;
    this.arrayAdapter = arrayAdapter;
    this.objects = objects;
}



@SuppressLint("ResourceAsColor")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

    View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_selection,null);

    setContentView(view);

    BodyMenuCard parentCard = view.findViewById(R.id.parentCard);
    parentCard.setHeader(header);

    TextView textView = parentCard.getCardBody().findViewById(R.id.bodyText);
    textView.setText(description);

    yesBtn = parentCard.getCardBody().findViewById(R.id.btn_yes);

    //spinner = parentCard.getCardBody().findViewById(R.id.employeeSpinner);
    spinner = view.findViewById(R.id.employeeSpinner);
    spinnerHandler = new EmployeeSpinnerHandler(getContext(), spinner, (List<Employee>) 
    toggleYesBtn(false);


    if (iconRessoruce != -1) parentCard.setIcon(iconRessoruce);
    if (backgroundColor != -1) parentCard.setCircleColor(backgroundColor);

    if (successfullCallback != null) yesBtn.setOnClickListener((v -> successfullCallback.onClick(this)));
    if (abbortCalllback != null) {
        parentCard.getCardBody().findViewById(R.id.btn_no).setOnClickListener((v -> abbortCalllback.onClick(this)));
    } else {
        parentCard.getCardBody().findViewById(R.id.btn_no).setOnClickListener(v -> this.dismiss());
    }
}

EmployeeSpinnerAdapter

public class EmployeeSpinnerAdapter extends ArrayAdapter<Employee> {

private Map<String, ColorStateList> employeeColors;

private List<Employee> employees;

private RandomMaterialColor randomColor;

public EmployeeSpinnerAdapter(Context context, List<Employee> employees) {
    super(context, R.layout.employee_spinner, employees);
    setDropDownViewResource(R.layout.employee_spinner);
    this.employees = employees;
    this.employeeColors = new HashMap<>();
}

private class ViewHolder {

    private GradientDrawable background;
    private TextView header;
    private TablePart idField;

    private ViewHolder(View view) {
        if (randomColor == null) randomColor = new RandomMaterialColor(view.getResources(), view.getContext());
        ImageView iv = view.findViewById(R.id.icon_view);
        background = (GradientDrawable) iv.getBackground().mutate();
        header = view.findViewById(R.id.header);
        idField = view.findViewById(R.id.description);
    }

    private void populate(Employee employee) {
        header.setText(employee.getName());
        idField.update(employee.getId());
        ColorStateList color = employeeColors.getOrDefault(employee.getId(), ColorStateList.valueOf(randomColor.getMatColor("A700")));
        background.setColor(color);
    }

}

@Override
public int getCount() {
    return employees.size();
}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    return obtainView(position, convertView, parent);
}

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) 
{
    return obtainView(position, convertView, parent);
}

private View obtainView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        convertView = mInflater.inflate(R.layout.employee_spinner, parent, false);
        convertView.setTag(new ViewHolder(convertView));
    }
    ViewHolder vh = (ViewHolder) convertView.getTag();
    vh.populate(employees.get(position));
    return convertView;
}
}

EmployeeSpinnerHandler 该类的目的是让在对话框内部和外部处理 Spinner 的代码完全相同,以找出错误。

public class EmployeeSpinnerHandler {

private Context context;

private Spinner spinner;

private EmployeeSpinnerAdapter adapter;

private List<Employee> employees;

public EmployeeSpinnerHandler(Context context, Spinner spinner, List<Employee> employees) {
    this.context = context;
    this.spinner = spinner;
    this.employees = employees;

    setUp();
}

private void setUp() {

    adapter = new EmployeeSpinnerAdapter(getContext(), employees);
    spinner.setAdapter(adapter);

    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            FancyToast.makeText(getContext(), "selected: " + employees.get(position).getName(), Toast.LENGTH_LONG, FancyToast.SUCCESS, true).show();
            //toggleYesBtn(true);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            //toggleYesBtn(false);
            FancyToast.makeText(getContext(), "selected: none", Toast.LENGTH_LONG, FancyToast.SUCCESS, true).show();
        }
    });

}

public void updateObjects(List<Employee> employees) {
    this.employees.clear();
    this.employees.addAll(employees);
    adapter.notifyDataSetChanged();
}
}

普通 Fragment 中的 Spinner

spinner = view.findViewById(R.id.employeeSpinner);
    EmployeeSpinnerHandler spinnerHandler = new EmployeeSpinnerHandler(getContext(), spinner, objects);

注意:在一般情况下,日期是从 REST-Api 获取的,但它仍然只适用于普通 Fragment。

现在的问题是,如果我在位于普通 Fragment 中的 Spinner 上使用 EmployeeSpinnerHandler 它可以工作,但是如果我在选择对话框中使用 Spinner,您可以单击微调器并显示项目,但它们不可选择(见图片)。

图片:

Custom Dialog with Spinner

Popup from Spinner in custom Dialog, were you can see the data is present, but if clicked it only closes the popup view

Spinner Working inside the Normal Fragment

【问题讨论】:

    标签: android dialog spinner custom-adapter customdialog


    【解决方案1】:

    适配器允许单一焦点视图使android:focusable="false" 用于所有其他项目android:focusable="true" 用于您的 TextView,它包含它将工作的标题。

    【讨论】:

      【解决方案2】:

      如果下面的代码返回一个项目,它似乎缺少视觉更新: FancyToast.makeText(getContext(), "selected:" + employees.get(position).getName(), Toast.LENGTH_LONG, FancyToast.SUCCESS, true).show();

      在这种情况下,我建议添加 spinner.setSelection(位置)

      【讨论】:

      • 但问题是这个方法永远不会在自定义对话框中被调用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多