add: file sorting

This commit is contained in:
hyb1996
2017-09-30 19:12:07 +08:00
parent c114148502
commit be022f1c94
15 changed files with 532 additions and 212 deletions

View File

@@ -1,42 +0,0 @@
package com.stardust.scriptdroid.script;
import java.io.File;
/**
* Created by Stardust on 2017/1/23.
*/
public abstract class ScriptFileList {
private static ScriptFileList impl;
public static void setImpl(ScriptFileList list) {
impl = list;
}
public static ScriptFileList getImpl() {
return impl;
}
public abstract void add(ScriptFile scriptFile);
public abstract ScriptFile get(int i);
public abstract void remove(int i);
public abstract void rename(int position, String newName, boolean renameFile);
public abstract int size();
public boolean deleteFromFileSystem(int i) {
if (i < 0 || i >= size())
return false;
File file = get(i);
remove(i);
return file.delete();
}
public abstract boolean containsPath(String path);
}

View File

@@ -1,103 +0,0 @@
package com.stardust.scriptdroid.script;
import android.content.Context;
import android.content.SharedPreferences;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.stardust.pio.PFile;
import com.stardust.scriptdroid.App;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/1/23.
*/
public class SharedPrefScriptFileList extends ScriptFileList {
private static final Gson GSON = new Gson();
private static final String SP_KEY_SCRIPT_NAME = "script_name";
private static final String SP_KEY_SCRIPT_PATH = "script_path";
private static ScriptFileList instance = new SharedPrefScriptFileList(App.getApp());
private SharedPreferences mSharedPreferences;
private List<String> mScriptPath;
private List<String> mScriptName;
public static ScriptFileList getInstance() {
return instance;
}
public SharedPrefScriptFileList(Context context) {
mSharedPreferences = context.getSharedPreferences("SharedPrefScriptFileList", Context.MODE_PRIVATE);
readFromSharedPref();
}
private void readFromSharedPref() {
Type type = new TypeToken<List<String>>() {
}.getType();
mScriptName = GSON.fromJson(mSharedPreferences.getString(SP_KEY_SCRIPT_NAME, ""), type);
mScriptPath = GSON.fromJson(mSharedPreferences.getString(SP_KEY_SCRIPT_PATH, ""), type);
if (mScriptName == null || mScriptPath == null || mScriptName.size() != mScriptPath.size()) {
reset();
}
}
private void reset() {
mScriptName = new ArrayList<>();
mScriptPath = new ArrayList<>();
syncWithSharedPref();
}
@Override
public void add(ScriptFile scriptFile) {
mScriptName.add(scriptFile.getSimplifiedName());
mScriptPath.add(scriptFile.getSimplifiedPath());
syncWithSharedPref();
}
@Override
public ScriptFile get(int i) {
return new ScriptFile(mScriptPath.get(i));
}
@Override
public void remove(int i) {
mScriptName.remove(i);
mScriptPath.remove(i);
syncWithSharedPref();
}
@Override
public void rename(int position, String newName, boolean renameFile) {
mScriptName.set(position, newName);
if (renameFile) {
String newPath = PFile.renameWithoutExtensionAndReturnNewPath(mScriptPath.get(position), newName);
mScriptPath.set(position, newPath);
}
syncWithSharedPref();
}
@Override
public int size() {
return mScriptPath.size();
}
@Override
public boolean containsPath(String path) {
return mScriptPath.contains(path);
}
protected void syncWithSharedPref() {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putString(SP_KEY_SCRIPT_NAME, GSON.toJson(mScriptName));
editor.putString(SP_KEY_SCRIPT_PATH, GSON.toJson(mScriptPath));
editor.apply();
}
}

View File

@@ -125,7 +125,7 @@ public class StorageFileProvider {
if (scriptFiles == null) {
return Observable.empty();
} else {
FileSorter.sort(scriptFiles);
FileSorter.sort(scriptFiles, FileSorter.NAME);
mScriptFileCache.put(dir.getPath(), scriptFiles);
return Observable.fromArray(scriptFiles);
}

View File

@@ -196,6 +196,7 @@ public class CodeMirrorEditor extends FrameLayout {
public void loadFile(final File file) {
setProgress(true);
// TODO: 2017/9/29 handle error
Observable.fromCallable(new Callable<String>() {
@Override
public String call() throws Exception {
@@ -346,20 +347,22 @@ public class CodeMirrorEditor extends FrameLayout {
@JavascriptInterface
public void setStringFromJs(String text) {
if (mStringFromJs != null) {
mStringFromJs.onNext(text);
mStringFromJs.onComplete();
mStringFromJs = null;
if (mStringFromJs == null) {
return;
}
mStringFromJs.onNext(text);
mStringFromJs.onComplete();
mStringFromJs = null;
}
@JavascriptInterface
public void setIntFromJs(int i) {
if (mIntFromJs != null) {
mIntFromJs.onNext(i);
mIntFromJs.onComplete();
mIntFromJs = null;
if (mIntFromJs == null) {
return;
}
mIntFromJs.onNext(i);
mIntFromJs.onComplete();
mIntFromJs = null;
}
@JavascriptInterface
@@ -371,26 +374,28 @@ public class CodeMirrorEditor extends FrameLayout {
@JavascriptInterface
public void onTextChange() {
if (mCallback != null) {
mWebView.post(new Runnable() {
@Override
public void run() {
mCallback.onChange();
}
});
if (mCallback == null) {
return;
}
mWebView.post(new Runnable() {
@Override
public void run() {
mCallback.onChange();
}
});
}
@JavascriptInterface
public void updateCodeCompletion(final int fromLine, final int fromCh, final int toLine, final int toCh, final String[] list) {
if (mCallback != null) {
mWebView.post(new Runnable() {
@Override
public void run() {
mCallback.updateCodeCompletion(fromLine, fromCh, toLine, toCh, list);
}
});
if (mCallback == null) {
return;
}
mWebView.post(new Runnable() {
@Override
public void run() {
mCallback.updateCodeCompletion(fromLine, fromCh, toLine, toCh, list);
}
});
}
}
@@ -459,7 +464,7 @@ public class CodeMirrorEditor extends FrameLayout {
@Override
public void onProgressChanged(WebView view, int newProgress) {
mProgressBar.setVisibility(newProgress == 100 ? VISIBLE : GONE);
mProgressBar.setVisibility(newProgress == 100 ? GONE : VISIBLE);
}
}
}

View File

@@ -0,0 +1,105 @@
package com.stardust.scriptdroid.ui.floating;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.view.ContextThemeWrapper;
import android.view.View;
import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.enhancedfloaty.ResizableFloaty;
import com.stardust.enhancedfloaty.ResizableFloatyWindow;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.scriptdroid.ui.edit.EditActivity_;
import com.stardust.scriptdroid.ui.edit.EditorView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import static com.stardust.scriptdroid.ui.edit.EditorView.EXTRA_NAME;
import static com.stardust.scriptdroid.ui.edit.EditorView.EXTRA_PATH;
/**
* Created by Stardust on 2017/9/29.
*/
public class EditorFloaty implements ResizableFloaty {
private Intent mIntent;
@BindView(R.id.resizer)
View mResizeIcon;
@BindView(R.id.move_cursor)
View mMoveIcon;
private ResizableFloatyWindow mWindow;
public EditorFloaty(Intent intent) {
mIntent = intent;
}
public static void floatingEdit(Context context, Intent intent) {
FloatyService.addWindow(new ResizableFloatyWindow(new EditorFloaty(intent)));
context.startService(new Intent(context, FloatyService.class));
}
public static void floatingEdit(Context context, String path) {
floatingEdit(context, null, path);
}
public static void floatingEdit(Context context, String name, String path) {
floatingEdit(context, new Intent(context, EditActivity_.class)
.putExtra(EXTRA_PATH, path)
.putExtra(EXTRA_NAME, name));
}
public static void floatingEdit(Context context, ScriptFile file) {
floatingEdit(context, file.getSimplifiedName(), file.getPath());
}
@Override
public View inflateView(FloatyService floatyService, ResizableFloatyWindow resizableFloatyWindow) {
mWindow = resizableFloatyWindow;
View v = View.inflate(new ContextThemeWrapper(floatyService, R.style.AppTheme), R.layout.floating_editor, null);
setUpViews(v);
return v;
}
private void setUpViews(View v) {
EditorView editorView = (EditorView) v.findViewById(R.id.editor_view);
editorView.handleIntent(mIntent);
ButterKnife.bind(this, v);
}
@OnClick(R.id.move_or_resize)
void showOrHideMoveAndResizeIcon() {
if (mResizeIcon.getVisibility() == View.VISIBLE) {
mResizeIcon.setVisibility(View.GONE);
mMoveIcon.setVisibility(View.GONE);
} else {
mResizeIcon.setVisibility(View.VISIBLE);
mMoveIcon.setVisibility(View.VISIBLE);
}
}
@OnClick(R.id.close)
void close() {
mWindow.close();
}
@Nullable
@Override
public View getResizerView(View view) {
return view.findViewById(R.id.resizer);
}
@Nullable
@Override
public View getMoveCursorView(View view) {
return view.findViewById(R.id.move_cursor);
}
}

View File

@@ -16,6 +16,7 @@ import com.stardust.scriptdroid.script.StorageFileProvider;
import com.stardust.scriptdroid.tool.SimpleObserver;
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.floating.EditorFloaty;
import com.stardust.scriptdroid.ui.main.FloatingActionMenu;
import com.stardust.scriptdroid.ui.main.ViewPagerFragment;
import com.stardust.util.BackPressedHandler;
@@ -56,7 +57,8 @@ public class MyScriptListFragment extends ViewPagerFragment implements BackPress
mScriptFileList.setOnScriptFileClickListener(new ScriptListView.OnScriptFileClickListener() {
@Override
public void onScriptFileClick(View view, ScriptFile file) {
Scripts.edit(file);
//Scripts.edit(file);
EditorFloaty.floatingEdit(getContext(), file);
}
});
}
@@ -112,6 +114,10 @@ public class MyScriptListFragment extends ViewPagerFragment implements BackPress
mFloatingActionMenu.collapse();
return true;
}
if(mScriptFileList.canGoBack()){
mScriptFileList.goBack();
return true;
}
return false;
}

View File

@@ -7,6 +7,7 @@ import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@@ -23,16 +24,24 @@ import com.stardust.scriptdroid.script.StorageFileProvider;
import com.stardust.scriptdroid.tool.SimpleObserver;
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.viewmodel.ScriptList;
import com.stardust.widget.BindableViewHolder;
import org.greenrobot.eventbus.Subscribe;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Action;
import io.reactivex.functions.BiConsumer;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
/**
@@ -46,14 +55,14 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
void onScriptFileClick(View view, ScriptFile file);
}
private ScriptList mScriptList = new ScriptList();
private RecyclerView mScriptListView;
private ScriptListAdapter mScriptListAdapter = new ScriptListAdapter();
private ArrayList<ScriptFile> mScriptFiles = new ArrayList<>();
private ArrayList<ScriptFile> mDirectories = new ArrayList<>();
private ScriptFile mCurrentDirectory;
private OnScriptFileClickListener mOnScriptFileClickListener;
private ScriptFile mSelectedScriptFile;
private StorageFileProvider mStorageFileProvider;
private boolean mDirSortMenuShowing = false;
public ScriptListView(Context context) {
super(context);
@@ -78,6 +87,16 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
mOnScriptFileClickListener = onScriptFileClickListener;
}
public boolean canGoBack() {
return !mCurrentDirectory.equals(mStorageFileProvider.getInitialDirectory());
}
public void goBack() {
mCurrentDirectory = mCurrentDirectory.getParentFile();
loadScriptList();
}
private void init() {
setOnRefreshListener(this);
mScriptListView = new RecyclerView(getContext());
@@ -95,7 +114,7 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
@Override
public int getSpanSize(int position) {
//For directories
if (position >= 1 && position <= mDirectories.size()) {
if (position >= 1 && position <= mScriptList.directoryCount()) {
return 1;
}
//For files and category
@@ -107,24 +126,30 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
private void loadScriptList() {
mScriptFiles.clear();
mDirectories.clear();
mScriptList.clear();
mStorageFileProvider.getDirectoryScriptFiles(mCurrentDirectory)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SimpleObserver<ScriptFile>() {
.collectInto(mScriptList, new BiConsumer<ScriptList, ScriptFile>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull ScriptFile file) {
if (file.isFile()) {
mScriptFiles.add(file);
} else {
mDirectories.add(file);
}
public void accept(ScriptList list, ScriptFile file) throws Exception {
list.add(file);
}
})
.observeOn(Schedulers.computation())
.doOnSuccess(new Consumer<ScriptList>() {
@Override
public void onComplete() {
public void accept(@NonNull ScriptList list) throws Exception {
Log.d("SSS", "before sort:" + Thread.currentThread());
list.sort();
Log.d("SSS", "after sort:" + Thread.currentThread());
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<ScriptList>() {
@Override
public void accept(@NonNull ScriptList list) throws Exception {
Log.d("SSS", "notifyDataSetChanged:" + Thread.currentThread());
mScriptList = list;
mScriptListAdapter.notifyDataSetChanged();
setRefreshing(false);
}
@@ -166,16 +191,54 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
case R.id.open_by_other_apps:
Scripts.openByOtherApps(mSelectedScriptFile);
break;
case R.id.action_sort_by_date:
sort(ScriptList.SORT_TYPE_DATE, mDirSortMenuShowing);
break;
case R.id.action_sort_by_type:
sort(ScriptList.SORT_TYPE_TYPE, mDirSortMenuShowing);
break;
case R.id.action_sort_by_name:
sort(ScriptList.SORT_TYPE_NAME, mDirSortMenuShowing);
break;
case R.id.action_sort_by_size:
sort(ScriptList.SORT_TYPE_SIZE, mDirSortMenuShowing);
break;
default:
return false;
}
return true;
}
private void sort(final int sortType, final boolean isDir) {
setRefreshing(true);
Observable.fromCallable(new Callable<ScriptList>() {
@Override
public ScriptList call() throws Exception {
if (isDir) {
mScriptList.sortDir(sortType);
} else {
mScriptList.sortFile(sortType);
}
return mScriptList;
}
})
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<ScriptList>() {
@Override
public void accept(@NonNull ScriptList o) throws Exception {
mScriptListAdapter.notifyDataSetChanged();
setRefreshing(false);
}
});
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// mStorageFileProvider.unregisterDirectoryChangeListener(this);
// mStorageFileProvider.unregisterDirectoryChangeListener(this);
}
private class ScriptListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@@ -202,23 +265,23 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
BindableViewHolder bindableViewHolder = (BindableViewHolder) holder;
if (position == 0 || position == mDirectories.size() + 1) {
if (position == 0 || position == mScriptList.directoryCount() + 1) {
bindableViewHolder.bind(position == 0, position);
return;
}
if (position <= mDirectories.size()) {
bindableViewHolder.bind(mDirectories.get(position - 1), position);
if (position <= mScriptList.directoryCount()) {
bindableViewHolder.bind(mScriptList.getDir(position - 1), position);
return;
}
bindableViewHolder.bind(mScriptFiles.get(position - mDirectories.size() - 2), position);
bindableViewHolder.bind(mScriptList.getFile(position - mScriptList.directoryCount() - 2), position);
}
@Override
public int getItemViewType(int position) {
if (position == 0 || position == mDirectories.size() + 1) {
if (position == 0 || position == mScriptList.directoryCount() + 1) {
return VIEW_TYPE_CATEGORY;
}
if (position <= mDirectories.size()) {
if (position <= mScriptList.directoryCount()) {
return VIEW_TYPE_DIRECTORY;
}
return VIEW_TYPE_FILE;
@@ -226,7 +289,7 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
@Override
public int getItemCount() {
return mScriptFiles.size() + mDirectories.size() + 2;
return mScriptList.count() + 2;
}
}
@@ -338,6 +401,11 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
@BindView(R.id.sort)
ImageView mSort;
@BindView(R.id.order)
ImageView mSortOrder;
private boolean mIsDir;
CategoryViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
@@ -346,11 +414,22 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
@Override
public void bind(Boolean isDirCategory, int position) {
mTitle.setText(isDirCategory ? R.string.text_directory : R.string.text_file);
mIsDir = isDirCategory;
}
@OnClick(R.id.order)
void changeSortOrder() {
if (mIsDir) {
mSortOrder.setImageResource(mScriptList.isDirSortedAscending() ?
R.drawable.ic_ascending_order : R.drawable.ic_descending_order);
mScriptList.setDirSortedAscending(!mScriptList.isDirSortedAscending());
sort(mScriptList.getDirSortType(), mIsDir);
} else {
mSortOrder.setImageResource(mScriptList.isFileSortedAscending() ?
R.drawable.ic_ascending_order : R.drawable.ic_descending_order);
mScriptList.setFileSortedAscending(!mScriptList.isFileSortedAscending());
sort(mScriptList.getFileSortType(), mIsDir);
}
}
@OnClick(R.id.sort)
@@ -358,7 +437,9 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
PopupMenu popupMenu = new PopupMenu(getContext(), mSort);
popupMenu.inflate(R.menu.menu_sort_options);
popupMenu.setOnMenuItemClickListener(ScriptListView.this);
mDirSortMenuShowing = mIsDir;
popupMenu.show();
}
}
}

View File

@@ -0,0 +1,113 @@
package com.stardust.scriptdroid.ui.viewmodel;
import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.util.FileSorter;
import java.io.File;
import java.util.ArrayList;
import java.util.Comparator;
/**
* Created by Stardust on 2017/9/30.
*/
public class ScriptList {
public static final int SORT_TYPE_NAME = 0x10;
public static final int SORT_TYPE_TYPE = 0x20;
public static final int SORT_TYPE_SIZE = 0x30;
public static final int SORT_TYPE_DATE = 0x40;
private ArrayList<ScriptFile> mScriptFiles = new ArrayList<>();
private ArrayList<ScriptFile> mDirectories = new ArrayList<>();
private int mDirSortType = SORT_TYPE_NAME;
private boolean mDirSortedAscending;
private boolean mFileSortedAscending;
private int mFileSortType = SORT_TYPE_NAME;
public boolean isDirSortedAscending() {
return mDirSortedAscending;
}
public boolean isFileSortedAscending() {
return mFileSortedAscending;
}
public int getDirSortType() {
return mDirSortType;
}
public int getFileSortType() {
return mFileSortType;
}
public void setDirSortedAscending(boolean dirSortedAscending) {
mDirSortedAscending = dirSortedAscending;
}
public void setFileSortedAscending(boolean fileSortedAscending) {
mFileSortedAscending = fileSortedAscending;
}
private Comparator<File> getComparator(int sortType) {
switch (sortType) {
case SORT_TYPE_NAME:
return FileSorter.NAME;
case SORT_TYPE_DATE:
return FileSorter.DATE;
case SORT_TYPE_SIZE:
return FileSorter.SIZE;
case SORT_TYPE_TYPE:
return FileSorter.TYPE;
}
throw new IllegalArgumentException("unknown type " + sortType);
}
public int directoryCount() {
return mDirectories.size();
}
public int fileCount() {
return mScriptFiles.size();
}
public void clear() {
mScriptFiles.clear();
mDirectories.clear();
}
public void add(ScriptFile file) {
if (file.isFile()) {
mScriptFiles.add(file);
} else {
mDirectories.add(file);
}
}
public ScriptFile getDir(int i) {
return mDirectories.get(i);
}
public ScriptFile getFile(int i) {
return mScriptFiles.get(i);
}
public int count() {
return mScriptFiles.size() + mDirectories.size();
}
public void sortDir(int sortType) {
mDirSortType = sortType;
FileSorter.sort(mDirectories, getComparator(sortType), mDirSortedAscending);
}
public void sortFile(int sortType) {
mFileSortType = sortType;
FileSorter.sort(mScriptFiles, getComparator(sortType), mFileSortedAscending);
}
public void sort() {
FileSorter.sort(mDirectories, getComparator(mDirSortType), mDirSortedAscending);
FileSorter.sort(mScriptFiles, getComparator(mFileSortType), mFileSortedAscending);
}
}

View File

@@ -59,6 +59,7 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setDomStorageEnabled(true);
settings.setDisplayZoomControls(false);
mWebView.setWebViewClient(new MyWebViewClient());
mWebView.setWebChromeClient(new MyWebChromeClient());
}

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.stardust.scriptdroid.ui.edit.EditorView_
android:id="@+id/editor_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.stardust.widget.ToolbarMenuItem
android:id="@+id/close"
android:layout_width="40dp"
android:layout_height="match_parent"
app:icon="@drawable/ic_close_white_48dp"
app:text="@string/text_close"/>
<com.stardust.widget.ToolbarMenuItem
android:id="@+id/move_or_resize"
android:layout_width="40dp"
android:layout_height="match_parent"
app:icon="@drawable/ic_settings_ethernet_white_24dp"
app:text="@string/text_adjust"/>
</LinearLayout>
<ImageView
android:id="@+id/resizer"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="@drawable/circle_cool_black"
android:padding="6dp"
android:scaleType="fitXY"
android:src="@drawable/ic_resizer"
android:tint="@android:color/white"
android:visibility="gone"/>
<ImageView
android:id="@+id/move_cursor"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="@drawable/circle_cool_black"
android:padding="5dp"
android:scaleType="fitXY"
android:src="@drawable/ic_move_cursor"
android:tint="@android:color/white"
android:visibility="gone"/>
</RelativeLayout>

View File

@@ -2,18 +2,18 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:checkable="true"
android:id="@+id/action_sort_by_name"
android:title="@string/text_name"/>
<item
android:checkable="true"
android:id="@+id/action_sort_by_date"
android:title="@string/text_time"
/>
<item
android:checkable="true"
android:id="@+id/action_sort_by_size"
android:title="@string/text_size"
/>
<item
android:checkable="true"
android:id="@+id/action_sort_by_type"
android:title="@string/text_type"
/>
</menu>

View File

@@ -279,6 +279,8 @@
<string name="text_refactor">重构</string>
<string name="text_select_variable">选择变量</string>
<string name="text_show_type">显示变量类型</string>
<string name="text_close">关闭</string>
<string name="text_adjust">调整</string>
<string-array name="record_control_keys">

View File

@@ -2,6 +2,15 @@ package com.stardust.scriptdroid;
import org.junit.Test;
import java.util.concurrent.Callable;
import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
/**
* Example local unit test, which will execute on the development machine (host).
*
@@ -17,11 +26,33 @@ public class ExampleUnitTest {
// TODO: 2017/7/4 细节 三天 7.18
// TODO: 2017/7/4 写文档 两天 7.20
// TODO: 2017/7/4 发布 3.0.0 Beta 7.22
// TODO: 2017/9/30 想象真是美好。
@Test
public void test() {
System.out.println("SOS".hashCode());
Observable.fromCallable(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread());
return "";
}
})
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.doOnComplete(new Action() {
@Override
public void run() throws Exception {
System.out.println(Thread.currentThread());
}
})
.observeOn(Schedulers.newThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(@NonNull String s) throws Exception {
System.out.println(Thread.currentThread());
}
});
}
@Test