Pic loading func, some animation
This commit is contained in:
parent
899be44eda
commit
0b4bf5f976
|
@ -37,7 +37,7 @@
|
||||||
<ConfirmationsSetting value="0" id="Add" />
|
<ConfirmationsSetting value="0" id="Add" />
|
||||||
<ConfirmationsSetting value="0" id="Remove" />
|
<ConfirmationsSetting value="0" id="Remove" />
|
||||||
</component>
|
</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" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="hikapro.com.backpack">
|
package="hikapro.com.backpack">
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".App"
|
android:name=".App"
|
||||||
|
|
|
@ -132,7 +132,7 @@ public class MainActivity extends Activity implements View.ActivityCallback {
|
||||||
presenter.setModel(model);
|
presenter.setModel(model);
|
||||||
model.setPresenter(presenter);
|
model.setPresenter(presenter);
|
||||||
|
|
||||||
replaceFragment(view, false, SetListFragment.class.getName());
|
replaceFragment(view, false, SetListFragment.class.getName(), false, false);
|
||||||
stateMaintainer.put(presenter);
|
stateMaintainer.put(presenter);
|
||||||
stateMaintainer.put(model);
|
stateMaintainer.put(model);
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ public class MainActivity extends Activity implements View.ActivityCallback {
|
||||||
presenter.setModel(model);
|
presenter.setModel(model);
|
||||||
model.setPresenter(presenter);
|
model.setPresenter(presenter);
|
||||||
|
|
||||||
replaceFragment(view, true, ItemListFragment.class.getName());
|
replaceFragment(view, true, ItemListFragment.class.getName(), true, true);
|
||||||
|
|
||||||
stateMaintainer.put(presenter);
|
stateMaintainer.put(presenter);
|
||||||
stateMaintainer.put(model);
|
stateMaintainer.put(model);
|
||||||
|
@ -168,14 +168,21 @@ public class MainActivity extends Activity implements View.ActivityCallback {
|
||||||
presenter.setModel(model);
|
presenter.setModel(model);
|
||||||
model.setPresenter(presenter);
|
model.setPresenter(presenter);
|
||||||
|
|
||||||
replaceFragment(view, true, ItemDetailFragment.class.getName());
|
replaceFragment(view, true, ItemDetailFragment.class.getName(), true, true);
|
||||||
|
|
||||||
stateMaintainer.put(presenter);
|
stateMaintainer.put(presenter);
|
||||||
stateMaintainer.put(model);
|
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();
|
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);
|
transaction.replace(R.id.container, fragment, tag);
|
||||||
if (addBackStack)
|
if (addBackStack)
|
||||||
transaction.addToBackStack(null);
|
transaction.addToBackStack(null);
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
package hikapro.com.backpack.model;
|
package hikapro.com.backpack.model;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.os.Message;
|
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.Item;
|
||||||
|
import hikapro.com.backpack.model.entities.Set;
|
||||||
import hikapro.com.backpack.presenter.Presenter;
|
import hikapro.com.backpack.presenter.Presenter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,9 +19,12 @@ public class DetailModel implements Model.Detail {
|
||||||
|
|
||||||
private Presenter.ItemDetail presenter;
|
private Presenter.ItemDetail presenter;
|
||||||
private Item item;
|
private Item item;
|
||||||
|
private DAO dao;
|
||||||
|
private Bitmap pic;
|
||||||
|
|
||||||
public DetailModel() {
|
public DetailModel() {
|
||||||
|
this.dao = DAO.getInstance();
|
||||||
|
dao.registerObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// detail -->
|
// detail -->
|
||||||
|
@ -28,6 +38,10 @@ public class DetailModel implements Model.Detail {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bitmap getPicture() {
|
||||||
|
return pic;
|
||||||
|
}
|
||||||
// detail <--
|
// detail <--
|
||||||
|
|
||||||
// events -->
|
// events -->
|
||||||
|
@ -52,7 +66,14 @@ public class DetailModel implements Model.Detail {
|
||||||
// process -->
|
// process -->
|
||||||
@Override
|
@Override
|
||||||
public void executeQuery() {
|
public void executeQuery() {
|
||||||
|
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
|
Message command;
|
||||||
|
command = Message.obtain();
|
||||||
|
command.what = Command.ITEM_GET_IMAGE;
|
||||||
|
command.arg1 = item.getId();
|
||||||
|
dao.executeCommand(command);
|
||||||
|
|
||||||
}
|
}
|
||||||
// process <--
|
// process <--
|
||||||
|
|
||||||
|
@ -61,7 +82,6 @@ public class DetailModel implements Model.Detail {
|
||||||
public void setPresenter(Presenter.ItemDetail presenter) {
|
public void setPresenter(Presenter.ItemDetail presenter) {
|
||||||
this.presenter = presenter;
|
this.presenter = presenter;
|
||||||
this.item = presenter.getCurrentItem();
|
this.item = presenter.getCurrentItem();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -72,5 +92,14 @@ public class DetailModel implements Model.Detail {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Message event) {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,7 +208,6 @@ public class ItemModel implements Model.Item {
|
||||||
command.what = Command.SET_GET_ITEMS;
|
command.what = Command.SET_GET_ITEMS;
|
||||||
command.arg1 = presenter.getCurrentSet().getId();
|
command.arg1 = presenter.getCurrentSet().getId();
|
||||||
dao.executeCommand(command);
|
dao.executeCommand(command);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package hikapro.com.backpack.model;
|
package hikapro.com.backpack.model;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -54,6 +55,7 @@ public interface Model {
|
||||||
interface Detail extends Base {
|
interface Detail extends Base {
|
||||||
int getCount();
|
int getCount();
|
||||||
hikapro.com.backpack.model.entities.Item findItem(int id);
|
hikapro.com.backpack.model.entities.Item findItem(int id);
|
||||||
|
Bitmap getPicture();
|
||||||
void setPresenter(Presenter.ItemDetail presenter);
|
void setPresenter(Presenter.ItemDetail presenter);
|
||||||
Presenter.ItemDetail getPresenter();
|
Presenter.ItemDetail getPresenter();
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ public interface Command {
|
||||||
int ITEM_PACK = 0x7A;
|
int ITEM_PACK = 0x7A;
|
||||||
int ITEM_UNPACK = 0x7B;
|
int ITEM_UNPACK = 0x7B;
|
||||||
int ITEM_GET_CATEGORIES = 0x7C;
|
int ITEM_GET_CATEGORIES = 0x7C;
|
||||||
|
int ITEM_GET_IMAGE = 0x7D;
|
||||||
|
|
||||||
int MY_LIST_POST = 0x8C;
|
int MY_LIST_POST = 0x8C;
|
||||||
int MY_LIST_ITEM_ADD = 0x8D;
|
int MY_LIST_ITEM_ADD = 0x8D;
|
||||||
|
|
|
@ -5,6 +5,8 @@ import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteException;
|
import android.database.sqlite.SQLiteException;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
@ -108,6 +110,7 @@ public class DAO {
|
||||||
|
|
||||||
SetTask setTask;
|
SetTask setTask;
|
||||||
ItemTask itemTask;
|
ItemTask itemTask;
|
||||||
|
ImageProviderTask imageProviderTask;
|
||||||
|
|
||||||
if (command != null) {
|
if (command != null) {
|
||||||
switch (command.what) {
|
switch (command.what) {
|
||||||
|
@ -170,6 +173,16 @@ public class DAO {
|
||||||
threadPool.execute(itemTask);
|
threadPool.execute(itemTask);
|
||||||
break;
|
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 :
|
case Command.MY_LIST_ITEM_ADD :
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -320,13 +333,48 @@ public class DAO {
|
||||||
db.close();
|
db.close();
|
||||||
return ret;
|
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) {
|
private List<Item> readItems(int setId) {
|
||||||
List<Item> ret = new ArrayList<>(256);
|
List<Item> ret = new ArrayList<>(256);
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
SQLiteDatabase db = null;
|
SQLiteDatabase db = null;
|
||||||
Item item;
|
Item item;
|
||||||
String query = String.format(
|
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.ItemsTable.TABLE_NAME,
|
||||||
Db.SetItemsTable.TABLE_NAME,
|
Db.SetItemsTable.TABLE_NAME,
|
||||||
Db.ItemsTable.COLUMN_ID,
|
Db.ItemsTable.COLUMN_ID,
|
||||||
|
@ -421,6 +469,32 @@ public class DAO {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
// updates
|
// 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) {
|
private int updateSetsOrder(List<Set> reorderedSet) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
SQLiteDatabase db = null;
|
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
|
//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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,8 +96,9 @@ public class Db {
|
||||||
values.put(COLUMN_PHOTO_URL, item.getPhotoUrl());
|
values.put(COLUMN_PHOTO_URL, item.getPhotoUrl());
|
||||||
if (item.getPhotoThumbUrl() != null)
|
if (item.getPhotoThumbUrl() != null)
|
||||||
values.put(COLUMN_PHOTO_THUMB_URL, item.getPhotoThumbUrl());
|
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());
|
values.put(COLUMN_PHOTO_THUMB_LOCAL, item.getName());
|
||||||
*/
|
*/
|
||||||
return values;
|
return values;
|
||||||
|
@ -120,6 +121,7 @@ public class Db {
|
||||||
}
|
}
|
||||||
item.setPhotoUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL)));
|
item.setPhotoUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL)));
|
||||||
item.setPhotoThumbUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL)));
|
item.setPhotoThumbUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL)));
|
||||||
|
item.setPhotoLocal(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_LOCAL)));
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ public interface Event {
|
||||||
int ITEM_PACK_ERROR = -0x17;
|
int ITEM_PACK_ERROR = -0x17;
|
||||||
int ITEM_UNPACK_ERROR = -0x18;
|
int ITEM_UNPACK_ERROR = -0x18;
|
||||||
int ITEM_CATEGORY_LOAD_ERROR = -0x19;
|
int ITEM_CATEGORY_LOAD_ERROR = -0x19;
|
||||||
|
int ITEM_IMAGE_LOAD_ERROR = -0x1A;
|
||||||
|
|
||||||
int ITEM_FROM_SET_DELETED = 0x14;
|
int ITEM_FROM_SET_DELETED = 0x14;
|
||||||
int ITEM_INSERTED = 0x15;
|
int ITEM_INSERTED = 0x15;
|
||||||
|
@ -32,6 +33,8 @@ public interface Event {
|
||||||
int ITEM_PACKED = 0x17;
|
int ITEM_PACKED = 0x17;
|
||||||
int ITEM_UNPACKED = 0x18;
|
int ITEM_UNPACKED = 0x18;
|
||||||
int ITEM_CATEGORY_LOAD_COMPLETED = 0x19;
|
int ITEM_CATEGORY_LOAD_COMPLETED = 0x19;
|
||||||
|
int ITEM_IMAGE_LOAD_COMPLETED = 0x1A;
|
||||||
|
|
||||||
|
|
||||||
int MY_LIST_POST_ERROR = -0x28;
|
int MY_LIST_POST_ERROR = -0x28;
|
||||||
int MY_LIST_ITEM_ADD_ERROR = -0x29;
|
int MY_LIST_ITEM_ADD_ERROR = -0x29;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,8 @@ public class Item implements Comparable<Item>, Serializable {
|
||||||
@Expose
|
@Expose
|
||||||
private String photoThumbUrl;
|
private String photoThumbUrl;
|
||||||
|
|
||||||
|
private String photoLocal;
|
||||||
|
|
||||||
public Item() {
|
public Item() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +106,14 @@ public class Item implements Comparable<Item>, Serializable {
|
||||||
this.photoThumbUrl = photoThumbUrl;
|
this.photoThumbUrl = photoThumbUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPhotoLocal() {
|
||||||
|
return photoLocal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhotoLocal(String photoLocal) {
|
||||||
|
this.photoLocal = photoLocal;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = name != null ? name.hashCode() : 0;
|
int result = name != null ? name.hashCode() : 0;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package hikapro.com.backpack.presenter;
|
package hikapro.com.backpack.presenter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.widget.DefaultItemAnimator;
|
import android.support.v7.widget.DefaultItemAnimator;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
@ -60,35 +61,6 @@ public class ItemDetailPresenter implements Presenter.ItemDetail {
|
||||||
}
|
}
|
||||||
// life cycle <--
|
// 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 -->
|
// process -->
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -110,6 +82,11 @@ public class ItemDetailPresenter implements Presenter.ItemDetail {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Model.Detail getModel() {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item getCurrentItem() {
|
public Item getCurrentItem() {
|
||||||
return item;
|
return item;
|
||||||
|
@ -136,6 +113,11 @@ public class ItemDetailPresenter implements Presenter.ItemDetail {
|
||||||
Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayPicture(Bitmap bitmap) {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
// other impl <--
|
// other impl <--
|
||||||
|
|
||||||
private View.ItemDetail getView() throws NullPointerException {
|
private View.ItemDetail getView() throws NullPointerException {
|
||||||
|
|
|
@ -51,9 +51,11 @@ public class ItemListPresenter implements Presenter.ItemList {
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
/*
|
|
||||||
if (savedInstanceState != null)
|
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);
|
android.view.View view = inflater.inflate(R.layout.fragment_item_list, container, false);
|
||||||
LinearLayoutManager llm = new LinearLayoutManager(getActivityContext());
|
LinearLayoutManager llm = new LinearLayoutManager(getActivityContext());
|
||||||
recycler = (RecyclerView) view.findViewById(R.id.items_recycler);
|
recycler = (RecyclerView) view.findViewById(R.id.items_recycler);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package hikapro.com.backpack.presenter;
|
package hikapro.com.backpack.presenter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -59,15 +60,14 @@ public interface Presenter {
|
||||||
interface ItemDetail extends Base {
|
interface ItemDetail extends Base {
|
||||||
void setView(hikapro.com.backpack.view.View.ItemDetail view);
|
void setView(hikapro.com.backpack.view.View.ItemDetail view);
|
||||||
void setModel(Model.Detail model);
|
void setModel(Model.Detail model);
|
||||||
|
Model.Detail getModel();
|
||||||
void notifyDataSetChanged();
|
void notifyDataSetChanged();
|
||||||
void showMessage(String message);
|
void showMessage(String message);
|
||||||
int getItemsCount();
|
|
||||||
void bindViewHolder(DetailViewHolder holder, int position);
|
|
||||||
DetailViewHolder createViewHolder(ViewGroup parent, int viewType);
|
|
||||||
void onDestroy(boolean isChangingConfiguration);
|
void onDestroy(boolean isChangingConfiguration);
|
||||||
android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
|
android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
|
||||||
void onSaveInstanceState(Bundle outState);
|
void onSaveInstanceState(Bundle outState);
|
||||||
Item getCurrentItem();
|
Item getCurrentItem();
|
||||||
|
void displayPicture(Bitmap bitmap);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
package hikapro.com.backpack.presenter.adapters;
|
package hikapro.com.backpack.presenter.adapters;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.ViewGroup;
|
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.presenter.Presenter;
|
||||||
import hikapro.com.backpack.view.recycler.DetailViewHolder;
|
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> {
|
public class ItemDetailAdapter extends RecyclerView.Adapter<DetailViewHolder> {
|
||||||
|
|
||||||
private Presenter.ItemDetail presenter;
|
private Presenter.ItemDetail presenter;
|
||||||
private int itemId;
|
|
||||||
|
|
||||||
public ItemDetailAdapter(Presenter.ItemDetail presenter) {
|
public ItemDetailAdapter(Presenter.ItemDetail presenter) {
|
||||||
this.presenter = presenter;
|
this.presenter = presenter;
|
||||||
|
@ -20,21 +23,33 @@ public class ItemDetailAdapter extends RecyclerView.Adapter<DetailViewHolder> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return presenter.getItemsCount();
|
return presenter.getModel().getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(DetailViewHolder holder, int position) {
|
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
|
@Override
|
||||||
public DetailViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,52 +71,52 @@ public class ItemDetailFragment extends Fragment implements hikapro.com.backpack
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
View view = presenter.onCreateView(inflater, container, savedInstanceState);
|
|
||||||
presenter.setView(this);
|
presenter.setView(this);
|
||||||
Log.i(this.toString(), "onCreateView");
|
View view = presenter.onCreateView(inflater, container, savedInstanceState);
|
||||||
|
Log.i(this.toString(), " onCreateView");
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
Log.i(this.toString(), "onActivityCreated");
|
Log.i(this.toString(), " onActivityCreated");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
Log.i(this.toString(), "onStart");
|
Log.i(this.toString(), " onStart");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Log.i(this.toString(), "onResume");
|
Log.i(this.toString(), " onResume");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
Log.i(this.toString(), "onStop");
|
Log.i(this.toString(), " onStop");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
presenter.onDestroy(true); // TODO isChangingConfigurations
|
presenter.onDestroy(true); // TODO isChangingConfigurations
|
||||||
Log.i(this.toString(), "onDestroyView");
|
Log.i(this.toString(), " onDestroyView");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
presenter.onDestroy(false); // TODO isChangingConfigurations
|
presenter.onDestroy(false); // TODO isChangingConfigurations
|
||||||
Log.i(this.toString(), "onDestroy");
|
Log.i(this.toString(), " onDestroy");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onDetach() {
|
public void onDetach() {
|
||||||
super.onDetach();
|
super.onDetach();
|
||||||
Log.i(this.toString(), "onDetach");
|
Log.i(this.toString(), " onDetach");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
Log.i(this.toString(), "onSaveInstanceState");
|
Log.i(this.toString(), " onSaveInstanceState");
|
||||||
}
|
}
|
||||||
|
|
||||||
// life cycle <--
|
// life cycle <--
|
||||||
|
|
|
@ -150,6 +150,7 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
|
presenter.onSaveInstanceState(outState);
|
||||||
Log.i(this.toString(), "onSaveInstanceState");
|
Log.i(this.toString(), "onSaveInstanceState");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue