【问题标题】:layout design Label/value detail to Label/Value edit布局设计标签/值详细信息到标签/值编辑
【发布时间】:2018-02-07 14:03:02
【问题描述】:

长期从事原生 android 开发的 Web 开发人员。 努力解决我认为对于新手来说非常常见的问题。

问题:我有一个可以编辑详细信息的详细信息屏幕。单击编辑按钮导航到编辑屏幕。除了“详细信息”屏幕是只读的,而“编辑”屏幕中的每个字段都是可编辑的,这些视图基本相同。

Example layout

我已阅读此处的材料设计指南 https://material.io/guidelines/components/text-fields.html#text-fields-layout 详细介绍了如何设计可编辑字段。

我还在这里阅读了有关 TextInputLayout 的信息: https://www.androidhive.info/2015/09/android-material-design-floating-labels-for-edittext/

我可以为详细信息屏幕上的每个标签/值字段模拟 TextInputLayout(请参阅示例布局),但是,这似乎需要做很多工作。

我认为理想情况下重复使用编辑表单字段会非常方便,但只需将它们标记为详细信息屏幕的只读。

我想向 Android 专家请教实现这一目标的“正确方法”。我宁愿不拼凑一个解决方案。这个坚果肯定以前被破解过,但是,显然我的谷歌搜索能力不足以找到它。

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

    您可以使用以下说明禁用您的 EditText 字段:

    https://stackoverflow.com/a/33582335/3268303

    应用程序通常会共享添加/编辑屏幕,但不一定要查看/编辑。

    此处是添加/编辑共享的示例:

    https://github.com/googlesamples/android-architecture/tree/todo-mvp/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/addedittask

    public class AddEditTaskPresenter implements AddEditTaskContract.Presenter,
        TasksDataSource.GetTaskCallback {
    
    @NonNull
    private final TasksDataSource mTasksRepository;
    
    @NonNull
    private final AddEditTaskContract.View mAddTaskView;
    
    @Nullable
    private String mTaskId;
    
    private boolean mIsDataMissing;
    
    /**
     * Creates a presenter for the add/edit view.
     *
     * @param taskId ID of the task to edit or null for a new task
     * @param tasksRepository a repository of data for tasks
     * @param addTaskView the add/edit view
     * @param shouldLoadDataFromRepo whether data needs to be loaded or not (for config changes)
     */
    public AddEditTaskPresenter(@Nullable String taskId, @NonNull TasksDataSource tasksRepository,
            @NonNull AddEditTaskContract.View addTaskView, boolean shouldLoadDataFromRepo) {
        mTaskId = taskId;
        mTasksRepository = checkNotNull(tasksRepository);
        mAddTaskView = checkNotNull(addTaskView);
        mIsDataMissing = shouldLoadDataFromRepo;
    
        mAddTaskView.setPresenter(this);
    }
    
    @Override
    public void start() {
        if (!isNewTask() && mIsDataMissing) {
            populateTask();
        }
    }
    
    @Override
    public void saveTask(String title, String description) {
        if (isNewTask()) {
            createTask(title, description);
        } else {
            updateTask(title, description);
        }
    }
    
    @Override
    public void populateTask() {
        if (isNewTask()) {
            throw new RuntimeException("populateTask() was called but task is new.");
        }
        mTasksRepository.getTask(mTaskId, this);
    }
    
    @Override
    public void onTaskLoaded(Task task) {
        // The view may not be able to handle UI updates anymore
        if (mAddTaskView.isActive()) {
            mAddTaskView.setTitle(task.getTitle());
            mAddTaskView.setDescription(task.getDescription());
        }
        mIsDataMissing = false;
    }
    
    @Override
    public void onDataNotAvailable() {
        // The view may not be able to handle UI updates anymore
        if (mAddTaskView.isActive()) {
            mAddTaskView.showEmptyTaskError();
        }
    }
    
    @Override
    public boolean isDataMissing() {
        return mIsDataMissing;
    }
    
    private boolean isNewTask() {
        return mTaskId == null;
    }
    
    private void createTask(String title, String description) {
        Task newTask = new Task(title, description);
        if (newTask.isEmpty()) {
            mAddTaskView.showEmptyTaskError();
        } else {
            mTasksRepository.saveTask(newTask);
            mAddTaskView.showTasksList();
        }
    }
    
    private void updateTask(String title, String description) {
        if (isNewTask()) {
            throw new RuntimeException("updateTask() was called but task is new.");
        }
        mTasksRepository.saveTask(new Task(title, description, mTaskId));
        mAddTaskView.showTasksList(); // After an edit, go back to the list.
    }
    }
    

    【讨论】:

    • 这是使用 MVP/Clean,对于新手 android 开发者来说这不是标准的方法。
    • 我同意,但提供它是为了完整性。前面概述了简单的方法。拉莫拉克在扩展它方面做得很好。谢谢
    • 感谢您的回答。但是,我不关心添加/编辑场景,更关心的是编辑/细节场景。但再次感谢您阅读并提供您的意见。
    【解决方案2】:

    拥有一个用于显示和编辑文本的EditText 是非常好的解决方案。您只需调用TextInputLayout 上的setEnabled() 方法即可在这些状态之间切换。从 UX 角度来看,更改文本颜色以及仅在启用模式下显示行是一个好主意。设计可以通过使用Android的状态资源来实现。

    【讨论】:

    • setEnabled 已被弃用。最好使用 inpuType=none
    • setEnabled()TextInputLayout 上对我来说很好
    • 是的,它可以工作,但已被弃用。使用不推荐使用的代码不是一个好主意。我
    • 好吧...酷。似乎我可以共享两个屏幕的视图,因为它们几乎相同,除了一个用于细节,一个用于编辑。我会开枪的。谢谢。
    【解决方案3】:

    我为什么要根据当前视图的类型以编程方式更改元素的输入类型。如果是编辑视图,我只使用默认值。另一方面,我以这种方式更改输入类型。

    editText1.setText("Your value text here");
    
    editText1.setInputType(InputType.TYPE_NULL); 
    

    我认为它很简单,但效果很好

    【讨论】:

      猜你喜欢
      • 2017-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多