Pic loading func, some animation

This commit is contained in:
Tariel Hlontsi 2016-05-11 21:28:22 +03:00
parent 899be44eda
commit 0b4bf5f976
22 changed files with 443 additions and 62 deletions

View File

@ -37,7 +37,7 @@
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="hikapro.com.backpack">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:name=".App"

View File

@ -132,7 +132,7 @@ public class MainActivity extends Activity implements View.ActivityCallback {
presenter.setModel(model);
model.setPresenter(presenter);
replaceFragment(view, false, SetListFragment.class.getName());
replaceFragment(view, false, SetListFragment.class.getName(), false, false);
stateMaintainer.put(presenter);
stateMaintainer.put(model);
@ -150,7 +150,7 @@ public class MainActivity extends Activity implements View.ActivityCallback {
presenter.setModel(model);
model.setPresenter(presenter);
replaceFragment(view, true, ItemListFragment.class.getName());
replaceFragment(view, true, ItemListFragment.class.getName(), true, true);
stateMaintainer.put(presenter);
stateMaintainer.put(model);
@ -168,14 +168,21 @@ public class MainActivity extends Activity implements View.ActivityCallback {
presenter.setModel(model);
model.setPresenter(presenter);
replaceFragment(view, true, ItemDetailFragment.class.getName());
replaceFragment(view, true, ItemDetailFragment.class.getName(), true, true);
stateMaintainer.put(presenter);
stateMaintainer.put(model);
}
private void replaceFragment(Fragment fragment, boolean addBackStack, String tag) {
private void replaceFragment(Fragment fragment, boolean addBackStack, String tag,
boolean transition, boolean x) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
if (transition) {
if (x)
transaction.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_out_right,
R.animator.slide_in_right, R.animator.slide_out_left);
}
transaction.replace(R.id.container, fragment, tag);
if (addBackStack)
transaction.addToBackStack(null);

View File

@ -1,8 +1,15 @@
package hikapro.com.backpack.model;
import android.graphics.Bitmap;
import android.os.Message;
import java.util.List;
import hikapro.com.backpack.model.dao.Command;
import hikapro.com.backpack.model.dao.DAO;
import hikapro.com.backpack.model.dao.Event;
import hikapro.com.backpack.model.entities.Item;
import hikapro.com.backpack.model.entities.Set;
import hikapro.com.backpack.presenter.Presenter;
/**
@ -12,9 +19,12 @@ public class DetailModel implements Model.Detail {
private Presenter.ItemDetail presenter;
private Item item;
private DAO dao;
private Bitmap pic;
public DetailModel() {
this.dao = DAO.getInstance();
dao.registerObserver(this);
}
// detail -->
@ -28,6 +38,10 @@ public class DetailModel implements Model.Detail {
return item;
}
@Override
public Bitmap getPicture() {
return pic;
}
// detail <--
// events -->
@ -52,7 +66,14 @@ public class DetailModel implements Model.Detail {
// process -->
@Override
public void executeQuery() {
notifyDataSetChanged();
Message command;
command = Message.obtain();
command.what = Command.ITEM_GET_IMAGE;
command.arg1 = item.getId();
dao.executeCommand(command);
}
// process <--
@ -61,7 +82,6 @@ public class DetailModel implements Model.Detail {
public void setPresenter(Presenter.ItemDetail presenter) {
this.presenter = presenter;
this.item = presenter.getCurrentItem();
}
@Override
@ -72,5 +92,14 @@ public class DetailModel implements Model.Detail {
@Override
public void onEvent(Message event) {
switch (event.what) {
case Event.ITEM_IMAGE_LOAD_ERROR :
break;
case Event.ITEM_IMAGE_LOAD_COMPLETED :
pic = (Bitmap) event.obj;
notifyDataSetChanged();
break;
}
}
}

View File

@ -208,7 +208,6 @@ public class ItemModel implements Model.Item {
command.what = Command.SET_GET_ITEMS;
command.arg1 = presenter.getCurrentSet().getId();
dao.executeCommand(command);
}
}
@Override

View File

@ -1,5 +1,6 @@
package hikapro.com.backpack.model;
import android.graphics.Bitmap;
import android.os.Message;
import java.util.List;
@ -54,6 +55,7 @@ public interface Model {
interface Detail extends Base {
int getCount();
hikapro.com.backpack.model.entities.Item findItem(int id);
Bitmap getPicture();
void setPresenter(Presenter.ItemDetail presenter);
Presenter.ItemDetail getPresenter();

View File

@ -19,6 +19,7 @@ public interface Command {
int ITEM_PACK = 0x7A;
int ITEM_UNPACK = 0x7B;
int ITEM_GET_CATEGORIES = 0x7C;
int ITEM_GET_IMAGE = 0x7D;
int MY_LIST_POST = 0x8C;
int MY_LIST_ITEM_ADD = 0x8D;

View File

@ -5,6 +5,8 @@ import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@ -108,6 +110,7 @@ public class DAO {
SetTask setTask;
ItemTask itemTask;
ImageProviderTask imageProviderTask;
if (command != null) {
switch (command.what) {
@ -170,6 +173,16 @@ public class DAO {
threadPool.execute(itemTask);
break;
case Command.ITEM_GET_IMAGE :
Item item = findItem(command.arg1);
if (item != null) {
imageProviderTask = new ImageProviderTask(Command.ITEM_GET_IMAGE,
Process.THREAD_PRIORITY_DEFAULT);
imageProviderTask.item = item;
threadPool.execute(imageProviderTask);
}
break;
case Command.MY_LIST_ITEM_ADD :
break;
@ -320,13 +333,48 @@ public class DAO {
db.close();
return ret;
}
private Item findItem(int id) {
Item ret = null;
Cursor cursor = null;
SQLiteDatabase db = null;
try {
db = getReadDB();
String query = String.format("SELECT * FROM %s a WHERE a.%s = %d LIMIT 1",
Db.ItemsTable.TABLE_NAME, Db.ItemsTable.COLUMN_ID, id);
cursor = db.rawQuery(query, null);
if (cursor.moveToNext()) {
ret = Db.ItemsTable.parseCursor(cursor);
}
} catch (Exception e) {
//TODO write to log here
} finally {
if (cursor != null)
cursor.close();
if (db != null)
db.close();
}
return ret;
}
private List<Item> readItems(int setId) {
List<Item> ret = new ArrayList<>(256);
Cursor cursor = null;
SQLiteDatabase db = null;
Item item;
String query = String.format(
"SELECT * FROM %s a INNER JOIN %s b ON a.%s = b.%s WHERE b.%s = ? AND b.%s <> 1 AND b.%s <> 1",
"SELECT a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s FROM %s a INNER JOIN %s b ON a.%s = b.%s WHERE b.%s = ? AND b.%s <> 1 AND b.%s <> 1",
Db.ItemsTable.COLUMN_ID,
Db.ItemsTable.COLUMN_NAME,
Db.ItemsTable.COLUMN_CATEGORY,
Db.ItemsTable.COLUMN_DESCRIPTION,
Db.ItemsTable.COLUMN_BUY_URLS,
Db.ItemsTable.COLUMN_PHOTO_URL,
Db.ItemsTable.COLUMN_PHOTO_THUMB_URL,
Db.ItemsTable.COLUMN_PHOTO_LOCAL,
Db.ItemsTable.COLUMN_PHOTO_THUMB_LOCAL,
Db.ItemsTable.TABLE_NAME,
Db.SetItemsTable.TABLE_NAME,
Db.ItemsTable.COLUMN_ID,
@ -421,6 +469,32 @@ public class DAO {
return ret;
}
// updates
private int updateItemLocalPic(int id, String path) {
int ret = 0;
SQLiteDatabase db = null;
ContentValues values;
try {
db = getWriteDB();
db.beginTransaction();
values = new ContentValues();
values.put(Db.ItemsTable.COLUMN_PHOTO_LOCAL, path);
ret = db.update(Db.ItemsTable.TABLE_NAME, values, "_id = ?",
new String[]{String.valueOf(id)});
db.setTransactionSuccessful();
} catch (SQLiteException e) {
//TODO write to log here
} catch (Exception e) {
//TODO write to log here
} finally {
if (db != null) {
db.endTransaction();
db.close();
}
}
return ret;
}
private int updateSetsOrder(List<Set> reorderedSet) {
int ret = 0;
SQLiteDatabase db = null;
@ -738,7 +812,67 @@ public class DAO {
}
}
}
// IMAGE PROVIDER CLASS
private class ImageProviderTask implements Runnable {
int currentCommand;
int priority;
Item item;
public ImageProviderTask(int command, int priority) {
this.currentCommand = command;
this.priority = priority;
}
@Override
public void run() {
android.os.Process.setThreadPriority(priority);
Message message = Message.obtain();
switch (currentCommand) {
case Command.ITEM_GET_IMAGE :
try {
Bitmap bitmap = loadItemImage(item);
if (bitmap != null) {
message.what = Event.ITEM_IMAGE_LOAD_COMPLETED;
message.obj = bitmap;
}
else
message.what = Event.ITEM_IMAGE_LOAD_ERROR;
} catch (Exception e) {
message.what = Event.ITEM_IMAGE_LOAD_ERROR;
}
break;
}
handler.sendMessage(message);
}
}
//endregion
private Bitmap loadItemImage(Item item){
ImageDownloadHelper downloadHelper = new ImageDownloadHelper();
Bitmap bitmap = null;
String filename = null;
if (item != null) {
bitmap = BitmapFactory.decodeFile(item.getPhotoLocal());
// cannot retrieve, download and save then
if (bitmap == null) { // return it
bitmap = downloadHelper.loadImage(item.getPhotoUrl());
if (bitmap != null) {
if (downloadHelper.isExternalStorageWritable()) {
filename = downloadHelper.saveImageExternal(
downloadHelper.generateFileName(item.getPhotoUrl()), bitmap);
} else {
filename = downloadHelper.saveImageInternal(
downloadHelper.generateFileName(item.getPhotoUrl()), bitmap);
}
updateItemLocalPic(item.getId(), filename);
}
}
}
return bitmap;
}
}

View File

@ -96,8 +96,9 @@ public class Db {
values.put(COLUMN_PHOTO_URL, item.getPhotoUrl());
if (item.getPhotoThumbUrl() != null)
values.put(COLUMN_PHOTO_THUMB_URL, item.getPhotoThumbUrl());
if (item.getPhotoLocal() != null)
values.put(COLUMN_PHOTO_LOCAL, item.getPhotoLocal());
/*
values.put(COLUMN_PHOTO_LOCAL, );
values.put(COLUMN_PHOTO_THUMB_LOCAL, item.getName());
*/
return values;
@ -120,6 +121,7 @@ public class Db {
}
item.setPhotoUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL)));
item.setPhotoThumbUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL)));
item.setPhotoLocal(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_LOCAL)));
return item;
}

View File

@ -25,6 +25,7 @@ public interface Event {
int ITEM_PACK_ERROR = -0x17;
int ITEM_UNPACK_ERROR = -0x18;
int ITEM_CATEGORY_LOAD_ERROR = -0x19;
int ITEM_IMAGE_LOAD_ERROR = -0x1A;
int ITEM_FROM_SET_DELETED = 0x14;
int ITEM_INSERTED = 0x15;
@ -32,6 +33,8 @@ public interface Event {
int ITEM_PACKED = 0x17;
int ITEM_UNPACKED = 0x18;
int ITEM_CATEGORY_LOAD_COMPLETED = 0x19;
int ITEM_IMAGE_LOAD_COMPLETED = 0x1A;
int MY_LIST_POST_ERROR = -0x28;
int MY_LIST_ITEM_ADD_ERROR = -0x29;

View File

@ -0,0 +1,145 @@
package hikapro.com.backpack.model.dao;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import hikapro.com.backpack.App;
/**
* Created by tariel on 04/05/16.
*/
public class ImageDownloadHelper {
public static final String ITEMS_TAG = "items";
private Context context;
public ImageDownloadHelper() {
this.context = App.getAppContext();
}
public Bitmap loadImage(String netPath) {
Bitmap bitmap = null;
try {
URL url = new URL(netPath);
URLConnection conn = url.openConnection();
bitmap = BitmapFactory.decodeStream(conn.getInputStream());
} catch (Exception ex) {
Log.e(ITEMS_TAG, " File cannot be downloaded");
}
return bitmap;
}
public boolean existsExternal(String filename) {
boolean ret = false;
if (isExternalStorageReadable()) {
File directory = getDir();
File file = new File(directory.getAbsoluteFile(), filename);
ret = file.exists();
}
return ret;
}
public boolean existsInternal(String filename) {
boolean ret = false;
File file = createTempFile(filename);
if (file != null) {
ret = file.exists();
}
return ret;
}
private File createTempFile(String fileName) {
File file = null;
try {
file = File.createTempFile(fileName, null, context.getCacheDir());
} catch (IOException e) {
Log.e(ITEMS_TAG, " Cannot obtain temp file");
}
return file;
}
public String generateFileName(String netPath) {
String ret = "";
if (netPath != null && !netPath.isEmpty()) {
ret = Uri.parse(netPath).getLastPathSegment();
}
return ret;
}
public String saveImageInternal(String filename, Bitmap bitmap) {
File file = null;
FileOutputStream outputStream;
if (bitmap != null && !filename.isEmpty()) {
file = createTempFile(filename);
if (file != null) {
try {
outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
Log.e(ITEMS_TAG, " File cannot be saved");
}
}
}
return file != null ? file.getAbsolutePath() : null;
}
public String saveImageExternal(String filename, Bitmap bitmap) {
File file = null;
FileOutputStream outputStream;
if (isExternalStorageWritable()) {
if (bitmap != null && !filename.isEmpty()) {
File directory = getDir();
file = new File(directory.getAbsoluteFile(), filename);
try {
outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
Log.e(ITEMS_TAG, " File cannot be saved");
}
}
}
return file != null ? file.getAbsolutePath() : null;
}
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
private File getDir() {
// Get the directory for the app's private pictures directory.
File file = new File(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), ITEMS_TAG);
if (!file.mkdirs()) {
Log.e(ITEMS_TAG, " Directory not created");
}
return file;
}
}

View File

@ -34,6 +34,8 @@ public class Item implements Comparable<Item>, Serializable {
@Expose
private String photoThumbUrl;
private String photoLocal;
public Item() {
}
@ -104,6 +106,14 @@ public class Item implements Comparable<Item>, Serializable {
this.photoThumbUrl = photoThumbUrl;
}
public String getPhotoLocal() {
return photoLocal;
}
public void setPhotoLocal(String photoLocal) {
this.photoLocal = photoLocal;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;

View File

@ -1,6 +1,7 @@
package hikapro.com.backpack.presenter;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
@ -60,35 +61,6 @@ public class ItemDetailPresenter implements Presenter.ItemDetail {
}
// life cycle <--
// recycler -->
@Override
public int getItemsCount() {
return model.getCount();
}
@Override
public void bindViewHolder(DetailViewHolder holder, int position) {
hikapro.com.backpack.model.entities.Item item = model.findItem(position);
holder.title.setText(item.getName());
holder.description.setText(item.getDescription());
holder.title.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(android.view.View view) {
showMessage("On detail click");
}
});
}
@Override
public DetailViewHolder createViewHolder(ViewGroup parent, int viewType) {
DetailViewHolder viewHolder;
android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_detail,
parent, false);
viewHolder = new DetailViewHolder(v);
return viewHolder;
}
// recycler <--
// process -->
@Override
@ -110,6 +82,11 @@ public class ItemDetailPresenter implements Presenter.ItemDetail {
this.model = model;
}
@Override
public Model.Detail getModel() {
return model;
}
@Override
public Item getCurrentItem() {
return item;
@ -136,6 +113,11 @@ public class ItemDetailPresenter implements Presenter.ItemDetail {
Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show();
}
@Override
public void displayPicture(Bitmap bitmap) {
}
// other impl <--
private View.ItemDetail getView() throws NullPointerException {

View File

@ -51,9 +51,11 @@ public class ItemListPresenter implements Presenter.ItemList {
}
@Override
public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/*
if (savedInstanceState != null)
set = (Set) savedInstanceState.getSerializable(BUNDLE_SET_LIST_KEY);*/
set = (Set) savedInstanceState.getSerializable(BUNDLE_SET_LIST_KEY);
else
set = getView().getSet();
android.view.View view = inflater.inflate(R.layout.fragment_item_list, container, false);
LinearLayoutManager llm = new LinearLayoutManager(getActivityContext());
recycler = (RecyclerView) view.findViewById(R.id.items_recycler);

View File

@ -1,6 +1,7 @@
package hikapro.com.backpack.presenter;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@ -59,15 +60,14 @@ public interface Presenter {
interface ItemDetail extends Base {
void setView(hikapro.com.backpack.view.View.ItemDetail view);
void setModel(Model.Detail model);
Model.Detail getModel();
void notifyDataSetChanged();
void showMessage(String message);
int getItemsCount();
void bindViewHolder(DetailViewHolder holder, int position);
DetailViewHolder createViewHolder(ViewGroup parent, int viewType);
void onDestroy(boolean isChangingConfiguration);
android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
void onSaveInstanceState(Bundle outState);
Item getCurrentItem();
void displayPicture(Bitmap bitmap);
}

View File

@ -1,8 +1,12 @@
package hikapro.com.backpack.presenter.adapters;
import android.graphics.Bitmap;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import hikapro.com.backpack.R;
import hikapro.com.backpack.model.Model;
import hikapro.com.backpack.presenter.Presenter;
import hikapro.com.backpack.view.recycler.DetailViewHolder;
@ -12,7 +16,6 @@ import hikapro.com.backpack.view.recycler.DetailViewHolder;
public class ItemDetailAdapter extends RecyclerView.Adapter<DetailViewHolder> {
private Presenter.ItemDetail presenter;
private int itemId;
public ItemDetailAdapter(Presenter.ItemDetail presenter) {
this.presenter = presenter;
@ -20,21 +23,33 @@ public class ItemDetailAdapter extends RecyclerView.Adapter<DetailViewHolder> {
@Override
public int getItemCount() {
return presenter.getItemsCount();
return presenter.getModel().getCount();
}
@Override
public void onBindViewHolder(DetailViewHolder holder, int position) {
presenter.bindViewHolder(holder, position);
hikapro.com.backpack.model.entities.Item item = presenter.getModel().findItem(position);
holder.title.setText(item.getName());
holder.description.setText(item.getDescription());
Bitmap bitmap = presenter.getModel().getPicture();
if (bitmap != null)
holder.photo.setImageBitmap(bitmap);
holder.title.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(android.view.View view) {
presenter.showMessage("On detail click");
}
});
}
@Override
public DetailViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return presenter.createViewHolder(parent, viewType);
DetailViewHolder viewHolder;
android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_detail,
parent, false);
viewHolder = new DetailViewHolder(v);
return viewHolder;
}
public void setItemId(int id) {
this.itemId = id;
}
}

View File

@ -71,52 +71,52 @@ public class ItemDetailFragment extends Fragment implements hikapro.com.backpack
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = presenter.onCreateView(inflater, container, savedInstanceState);
presenter.setView(this);
Log.i(this.toString(), "onCreateView");
View view = presenter.onCreateView(inflater, container, savedInstanceState);
Log.i(this.toString(), " onCreateView");
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i(this.toString(), "onActivityCreated");
Log.i(this.toString(), " onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
Log.i(this.toString(), "onStart");
Log.i(this.toString(), " onStart");
}
@Override
public void onResume() {
super.onResume();
Log.i(this.toString(), "onResume");
Log.i(this.toString(), " onResume");
}
@Override
public void onStop() {
super.onStop();
Log.i(this.toString(), "onStop");
Log.i(this.toString(), " onStop");
}
@Override
public void onDestroyView() {
super.onDestroyView();
presenter.onDestroy(true); // TODO isChangingConfigurations
Log.i(this.toString(), "onDestroyView");
Log.i(this.toString(), " onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
presenter.onDestroy(false); // TODO isChangingConfigurations
Log.i(this.toString(), "onDestroy");
Log.i(this.toString(), " onDestroy");
}
@Override
public void onDetach() {
super.onDetach();
Log.i(this.toString(), "onDetach");
Log.i(this.toString(), " onDetach");
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(this.toString(), "onSaveInstanceState");
Log.i(this.toString(), " onSaveInstanceState");
}
// life cycle <--

View File

@ -150,6 +150,7 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
presenter.onSaveInstanceState(outState);
Log.i(this.toString(), "onSaveInstanceState");
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="x"
android:valueFrom="1000"
android:valueTo="0"
android:valueType="floatType" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="x"
android:valueFrom="-1000"
android:valueTo="0"
android:valueType="floatType" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="x"
android:valueFrom="0"
android:valueTo="1000"
android:valueType="floatType" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="x"
android:valueFrom="0"
android:valueTo="-1000"
android:valueType="floatType" />
</set>