У меня была такая же проблема. Я смог исправить это, установив язык, прежде чем пытаться отформатировать дату:
<fmt:setLocale value="en_US" />
<fmt:formatDate value="${now}" pattern="yyyy-MM-dd" />
Это устранило проблему, но я не знаю почему.
Используя Класс приложений
В зависимости от того, что Вы делаете в своей инициализации, Вы могли рассмотреть создание нового класса, который расширяется Application
и перемещение Вашего кода инициализации в переопределенный onCreate
метод в том классе.
public class MyApplicationClass extends Application {
@Override
public void onCreate() {
super.onCreate();
// TODO Put your application initialization code here.
}
}
onCreate
в классе приложений только назван, когда целое приложение создается, таким образом, перезапуски Действия на ориентации или изменениях видимости клавиатуры не инициируют его.
Это - хорошая практика для представления экземпляра этого класса как одиночный элемент и представление переменных приложения, Вы инициализируете методов get использования и методы set.
ПРИМЕЧАНИЕ: необходимо будет определить название нового Класса приложений в декларации для него, чтобы регистрироваться и использоваться:
<application
android:name="com.you.yourapp.MyApplicationClass"
Реакция на Изменения конфигурации [ОБНОВЛЕНИЕ: это удерживается от использования начиная с API 13; видят рекомендуемую альтернативу ]
Как дальнейшая альтернатива, у Вас может быть свое приложение, прислушиваются к событиям, которые вызвали бы перезапуск †“как ориентация, и видимость клавиатуры изменяет †“, и обработайте их в рамках своего Действия.
Запускаются путем добавления android:configChanges
узел к явному узлу Действия
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">
или для [1 112] (Уровень API 13) Android 3.2 и более новый :
<activity android:name=".MyActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name">
Тогда в рамках Действия переопределяют onConfigurationChanged
метод и вызов setContentView
, чтобы вынудить расположение GUI быть восстановленным в новой ориентации.
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.myLayout);
}
Один из лучших компонентов Android Architechure, представленный Google, удовлетворит все ваши требования ViewModel.
Это предназначено для хранения и управления данными, относящимися к пользовательскому интерфейсу, в режиме жизненного цикла, а также позволит выживать данным при повороте экрана.
class MyViewModel : ViewModel() {
Пожалуйста, обратитесь сюда: https://developer.android. ком / тема / библиотеки / архитектура / ViewModel
вам нужно использовать метод onSavedInstanceState, чтобы сохранить все значения для его параметра, который имеет связку
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
outPersistentState.putBoolean("key",value);
}
и использовать
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getBoolean("key");
}
, чтобы извлечь и установить значение на просматривать объекты он будет обрабатывать поворот экрана
Каждый раз, когда экран поворачивается, открытое действие заканчивается и снова вызывается onCreate ().
1. Вы можете сделать одно, сохранить состояние активности при повороте экрана, чтобы вы могли восстановить все старые вещи, когда функция onCreate () вызывается снова. См. эту ссылку
2. Если вы хотите предотвратить перезапуск действия, просто поместите следующие строки в файле manifest.xml.
<activity android:name=".Youractivity"
android:configChanges="orientation|screenSize"/>
Я нашел способ сделать это, используя события onRestoreInstanceState
и onSaveInstanceState
для сохранения чего-либо в Bundle
(даже если вам не нужны сохраненные переменные, просто поместите что-нибудь туда, чтобы Bundle
] не пусто). Затем, с помощью метода onCreate
, проверьте, является ли Bundle
пустым, и если это так, то выполните инициализацию, если нет, то сделайте это.
Изменения, которые должны быть сделаны в манифесте Android:
android:configChanges="keyboardHidden|orientation"
Внесены дополнения в действие:
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
Я просто добавил
android:configChanges="keyboard|keyboardHidden|orientation"
в файл манифеста, а не добавил никакой метод onConfigurationChanged
в мою деятельность.
Так что каждый раз, когда клавиатура выдвигается или ничего не происходит .
Вы также можете рассмотреть возможность использования платформы Android для сохранения данных при изменении ориентации: onRetainNonConfigurationInstance()
и getLastNonConfigurationInstance()
.
Это позволяет вам сохранять данные при изменениях конфигурации, такие как информация, которую вы, возможно, получили из выборки с сервера, или что-то еще, что было вычислено в onCreate
или с тех пор, а также позволяет Android изменять макет вашего Activity
, используя XML-файл для ориентации в настоящее время используется.
Следует отметить, что эти методы в настоящее время устарели (хотя они по-прежнему более гибкие, чем управление изменением ориентации самостоятельно, как предполагает большинство из приведенных выше решений) с рекомендацией, чтобы все переключились на Fragments
и вместо этого использовали setRetainInstance(true)
на каждом Fragment
вы хотите сохранить.
Через некоторое время проб и ошибок я нашел решение, которое соответствует моим потребностям в большинстве ситуаций. Вот код:
Конфигурация манифеста:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pepperonas.myapplication">
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
MainActivity:
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private Fragment mFragment;
private int mSelected = -1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate " + "");
// null check not realy needed - but just in case...
if (savedInstanceState == null) {
initUi();
// get an instance of FragmentTransaction from your Activity
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
/*IMPORTANT: Do the INITIAL(!) transaction only once!
* If we call this everytime the layout changes orientation,
* we will end with a messy, half-working UI.
* */
mFragment = FragmentOne.newInstance(mSelected = 0);
fragmentTransaction.add(R.id.frame, mFragment);
fragmentTransaction.commit();
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG, "onConfigurationChanged " +
(newConfig.orientation
== Configuration.ORIENTATION_LANDSCAPE
? "landscape" : "portrait"));
initUi();
Log.i(TAG, "onConfigurationChanged - last selected: " + mSelected);
makeFragmentTransaction(mSelected);
}
/**
* Called from {@link #onCreate} and {@link #onConfigurationChanged}
*/
private void initUi() {
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate instanceState == null / reinitializing..." + "");
Button btnFragmentOne = (Button) findViewById(R.id.btn_fragment_one);
Button btnFragmentTwo = (Button) findViewById(R.id.btn_fragment_two);
btnFragmentOne.setOnClickListener(this);
btnFragmentTwo.setOnClickListener(this);
}
/**
* Not invoked (just for testing)...
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d(TAG, "onSaveInstanceState " + "YOU WON'T SEE ME!!!");
}
/**
* Not invoked (just for testing)...
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.d(TAG, "onSaveInstanceState " + "YOU WON'T SEE ME, AS WELL!!!");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume " + "");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause " + "");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy " + "");
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_fragment_one:
Log.d(TAG, "onClick btn_fragment_one " + "");
makeFragmentTransaction(0);
break;
case R.id.btn_fragment_two:
Log.d(TAG, "onClick btn_fragment_two " + "");
makeFragmentTransaction(1);
break;
default:
Log.d(TAG, "onClick null - wtf?!" + "");
}
}
/**
* We replace the current Fragment with the selected one.
* Note: It's called from {@link #onConfigurationChanged} as well.
*/
private void makeFragmentTransaction(int selection) {
switch (selection) {
case 0:
mFragment = FragmentOne.newInstance(mSelected = 0);
break;
case 1:
mFragment = FragmentTwo.newInstance(mSelected = 1);
break;
}
// Create new transaction
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.frame, mFragment);
/*This would add the Fragment to the backstack...
* But right now we comment it out.*/
// transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
И Фрагмент образца:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* @author Martin Pfeffer (pepperonas)
*/
public class FragmentOne extends Fragment {
private static final String TAG = "FragmentOne";
public static Fragment newInstance(int i) {
Fragment fragment = new FragmentOne();
Bundle args = new Bundle();
args.putInt("the_id", i);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView " + "");
return inflater.inflate(R.layout.fragment_one, container, false);
}
}
Можно найти на github .
То, что вы описываете, является поведением по умолчанию. Вы должны обнаружить и обработать эти события самостоятельно, добавив:
android:configChanges
в свой манифест и затем изменения, которые вы хотите обработать. Таким образом, для ориентации вы должны использовать:
android:configChanges="orientation"
, а для открытия или закрытия клавиатуры вы должны использовать:
android:configChanges="keyboardHidden"
Если вы хотите обрабатывать оба, вы можете просто разделить их с помощью команда pipe, например:
android:configChanges="keyboardHidden|orientation"
. Это вызовет метод onConfigurationChanged в любой операции, которую вы вызываете. Если вы переопределите метод, вы можете передать новые значения.
Надеюсь, это поможет.
не ошибается, потому что он не семантичен. Это неправильно (обычно), потому что это презентационное. Отделение заботы означает, что преданная информация должна быть передана с CSS.
Наименование в целом может быть сложно, чтобы получить правильно, а имена классов не являются исключением, но тем не менее, это то, что вы должны сделать. Если вы используете курсив, чтобы сделать блок выделяться из текста тела, то, возможно, название класса «FILL-отличительный» будет в порядке. Подумайте о повторном использовании: имена классов предназначены для категоризации - где еще вы хотите сделать то же самое? Это должно помочь вам определить подходящее имя.
включен в HTML5, но оно дано определенная семантика. Если причина, по которой вы маркируете что-то, как италический, соответствует одной из семантиков, идентифицированной в спецификации, было бы целесообразно использовать
. В противном случае нет.
Метод
метод
все еще называется даже при изменении ориентации
Android. Поэтому перемещение всей тяжелой функциональности для этого метода не поможет вам