0

Long time web developer starting native android development. Struggling with what i would think to be a very common question for newbies.

Question: I have a Detail screen with the ability to edit the details. Clicking the edit button navigates to the Edit screen. The views are essentially identical with the exception that the Detail screen is read-only and the Edit screen where each field is editable.

Example layout

I've read through the Material Design guidelines here https://material.io/guidelines/components/text-fields.html#text-fields-layout and it goes into great detail on how to design editable fields.

I've also read about the TextInputLayout here: https://www.androidhive.info/2015/09/android-material-design-floating-labels-for-edittext/

I could emulate the TextInputLayout for each label/value field on the Detail screen (see Example layout), however, that seems like a lot of work.

I think ideally it would be very convenient to re-use the Edit form fields but just mark them as read-only for the Detail screen.

I wanted to ask the Android gurus out there the "right way" to achieve this. I would rather not hack together a solution. Surely this nut has been cracked before, however, apparently my Googling skills are not good enough to find it.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Robert Taylor
  • 21
  • 1
  • 4

3 Answers3

1

You can disable your EditText fields using the following instructions:

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

Applications will normally share add/edit screens, but not necessarily view/edit.

An example of add/edit sharing is here:

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.
}
}
dazza5000
  • 7,075
  • 9
  • 44
  • 89
  • This is using MVP/Clean, which is not quite the standard approach for newbie android developers. – Shark Feb 07 '18 at 14:28
  • I agree, but provided it for completeness. The simple approach is outlined before it. Lamorak did a good job expanding on it. Thank you – dazza5000 Feb 07 '18 at 14:32
  • Thanks for the answer. However, I'm not concerned with the add/edit scenario, more with the edit/detail scenario. But again, thanks for reading and providing your input. – Robert Taylor Feb 08 '18 at 00:30
1

Having an EditText for both displaying and editing text is perfectly OK solution. You can just call the setEnabled() method onthe TextInputLayout to switch between those states. From UX perspective it is a good idea to change colors of the text as well as showing the line only in enabled mode. The design can be achieved by using Android's state resources.

Lamorak
  • 10,957
  • 9
  • 43
  • 57
0

why i use to do is to changue the input type of the element programatically depending in the kind of the current view. If it is edit view i just use the default values. In the other hand, i changue the input type this way.

editText1.setText("Your value text here");

editText1.setInputType(InputType.TYPE_NULL); 

i think it simple an ti works well