У меня есть Fragment
внутри его собственной Activity
предназначен для срабатывать через intent
, который позволяет для использования startActivityForResult
, текущее использование случай редактировать запись в ListView
и работает отлично, но дайте мне знать, если я m используя неправильный шаблон. Исходящий Activity
проверяет данные во время его onActivityResult
и может решить, что есть что-то неприемлемое (например, запись не будет считаться уникальной), и в этом случае он запускает новый Intent
для того же «редактирования» Activity
, используя те же данные, которые он получил при добавлении запись в расширенные данные с описательной причиной (например, «Имя уже используется»); если это поле существует, тогда «редактирование» Fragment
должно отображать Toast
с этим сообщением. Я попытался отобразить Toast
в разных точках начальной иерархии его жизненного цикла onResume
, который, как мне кажется, из документов, является последним, но опять же исправляйте меня, если я ошибаюсь. На моем реальном S4 он выглядит хорошо, но если я запустил его на медленном эмуляторе, тошень заработает намного меньше секунды (он получил Toast.LENGTH_SHORT
, так что он должен длиться 2 секунды), поэтому он, кажется, создается до вид фактически перерисован.Android: Показывает тост за его полную продолжительность после перерисовки Фрагмента - где на жизненном цикле он должен показывать()?
В моем текущем варианте использования я мог бы сменить модель на передачу данных, по которым должны быть сделаны проверки в качестве части оригинала Intent
, но это кажется мне неправильным - может быть, данные будут большими или нет но доступен или, может быть, «редактор» Activity
- это тот, который должен быть общим, и в этом случае он, конечно же, не должен иметь случаев обработки кода для разных абонентов.
Итак, где должен быть вызван метод Toast's
show
таким образом, чтобы на самом деле пользователю было гарантировано увидеть его в течение всей продолжительности?
Примечание: Я уверен, что на этот вопрос действительно не нужен код, так как кто-то с опытом должен быть в состоянии просто сказать, где в lifecyle будет правильное местоположение, и если я сделаю кнопку, которая показывает тост при нажатии, он отображается в течение 2 секунд на одном и том же эмуляторе, но в случае необходимости я, вероятно, мог бы сбить пример с урезанной стороной.
EDIT ОК, здесь приведен пример кода. Обратите внимание, что я использую json в настоящее время, но сделаю мои объекты Parcelable в какой-то момент (я Android и Java n00b, поэтому не читал об этом до тех пор, пока не перешел в мою реализацию - так что это в моем списке TODO).
PlayersFragment (содержащий адаптер в списке объектов игрока) имеет следующие методы
private AdapterView.OnItemClickListener itemClickListener =
new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int index, long id) {
edit(index, myActivity.getPlayer(index), "");
}
};
private void edit(int index, Player toEdit, String toastMessage) {
Intent intent = new Intent(myActivity, PlayerEditor.class);
intent.putExtra(PLAYERS_INDEX, index);
intent.putExtra(JSON_PLAYER, gson.toJson(toEdit));
if (!toastMessage.equals("")) { intent.putExtra(TOAST_MESSAGE, toastMessage); }
startActivityForResult(intent, REQUEST_CODE_EDIT);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == REQUEST_CODE_EDIT && resultCode == Activity.RESULT_OK) {
int playerIndex = intent.getIntExtra(PLAYERS_INDEX, -1);
int size = myActivity.getPlayersSize();
if (intent.hasExtra(PLAYERS_INDEX) && playerIndex >= 0 && playerIndex <= size) {
Player player = gson.fromJson(intent.getStringExtra(JSON_PLAYER),
new TypeToken<Player>(){}.getType());
if (playerIndex == size) { // A new player was created and saved or deleted
if (player != null) { // new but null implies deleted - nothing needs to be done
if (myActivity.addPlayer(player)) {
adapter.notifyDataSetChanged();
playerListView.setSelection(playerIndex);
} else {
edit(playerIndex, player, "Player name already in use");
}
}
} else { // a player was selected for edit and saved or deleted
if (myActivity.setPlayer(playerIndex, player)) {
adapter.notifyDataSetChanged();
}
else {
edit(playerIndex, player, "Player name already in use.");
}
}
}
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_players, container, false);
playerListView = (ListView) view.findViewById(R.id.playerList);
playerListView.setAdapter(adapter);
playerListView.setOnItemClickListener(itemClickListener);
ImageButton btnPlayerAdd = (ImageButton) view.findViewById(R.id.btnPlayerAdd);
btnPlayerAdd.setOnClickListener(OnClickListenerBtnPlayerAdd);
return view;
}
View.OnClickListener OnClickListenerBtnPlayerAdd = new View.OnClickListener() {
@Override
public void onClick(View view) {
// When adding a new player we go straight to the editor with a new player and an index
// one greater than currently exists (i.e. the ArrayList's size).
Player player = new Player();
int index = myActivity.getPlayersSize();
edit(index, player, "");
}
};
Затем PlayerEditor активность имеет этот метод:
private void returnToSender() {
//TODO: can this just be Intent()?
Intent intent = new Intent(this, MyActivity.class);
intent.putExtra(PLAYERS_INDEX, playersIndex);
if (player == null) { intent.putExtra(JSON_PLAYER, ""); }
else { intent.putExtra(JSON_PLAYER, gson.toJson(player)); }
setResult(Activity.RESULT_OK, intent);
finish();
}
PlayerEditorFragment, внутри PlayerEditor активность, затем имеет:
View.OnClickListener OnClickListenerBtnSave = new View.OnClickListener() {
@Override
public void onClick(View view) {
String chips = ((TextView) view.getRootView()
.findViewById(R.id.playerEditorChipsValue)).getText().toString();
if (chips.equals("")) { chips = "0"; }
playerEditor.player.setChips(new BigInteger(chips));
String name = ((TextView) view.getRootView()
.findViewById(R.id.playerEditorNameValue)).getText().toString();
playerEditor.player.setName(name);
playerEditor.returnToSender();
}
};
View.OnClickListener OnClickListenerBtnDelete = new View.OnClickListener() {
@Override
public void onClick(View view) {
playerEditor.player = null;
playerEditor.returnToSender();
}
};
@Override
public void onResume() {
super.onResume();
if (playerEditor.toastMessage != null) {
Toast toast = Toast.makeText(getActivity(), playerEditor.toastMessage
, Toast.LENGTH_SHORT);
toast.show();
}
}
- код в onResume is wh я не уверен, где разместить, поскольку я сказал, что это нормально, когда я запускаю его на своем устройстве, но запуск его на медленном эмуляторе, по-видимому, показывает тот факт, что отображаемая продолжительность может быть намного меньше, чем 2-секундное значение по умолчанию Toast.LENGTH_SHORT.
EDIT 2 Мой план для этого теперь переместить данные моего приложения к экземпляру приложения, а не основной деятельности (который всегда был неправ), и только передать индекс объекта в ArrayList с помощью намерения; таким образом редактор может выполнять проверки сам; или в более сложных сценариях попросите приложение выполнить проверку.
Это означает, что тост обычно не должен срабатывать при возобновлении. Однако он все еще не отвечает на вопрос, который эта ситуация скупала.
Элемент списка действительно представляет собой отдельный класс сущности. Кнопка сохранения «редактора» срабатывает с целью возвращения. Как я уже сказал, onActivityResult в составителе выполняет проверки, и если он решает, что есть причина, это неприемлемо, это добавляет эту причину к расширенным данным реплики Intent. Объект объекта списка не может выполнять проверки изолированно (это действительно весь список, который будет проверяться). Я посмотрю на диаграмму из Android Studio ... –
Сохраните объекты в новом классе, который отслеживает список для вас? Таким образом, вы можете повторно использовать функциональные возможности проверок в любом месте, где они вам нужны, а не просто в действии, в котором вы сейчас работаете. Вам действительно не нужен ваш код проверки в вашем графическом коде GUI. –
А-а ... это имеет смысл. TBH. Я не вижу в нем ясности из документации, в которой я собираюсь сохранить свои объекты - кажется, полностью ориентирован на пользовательский интерфейс! –