add: tutorial tab
This commit is contained in:
@@ -26,7 +26,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
* Created by Stardust on 2017/1/23.
|
||||
*/
|
||||
|
||||
public abstract class BaseActivity extends AppCompatActivity {
|
||||
public abstract class BaseActivity extends AppCompatActivity implements BackPressedHandler.HostActivity {
|
||||
|
||||
|
||||
protected static final int PERMISSION_REQUEST_CODE = 11186;
|
||||
@@ -123,4 +123,9 @@ public abstract class BaseActivity extends AppCompatActivity {
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackPressedHandler.Observer getBackPressedObserver() {
|
||||
return mBackPressObserver;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,9 +106,9 @@ public class EditActivity extends Editor920Activity implements OnActivityResultD
|
||||
@ViewById(R.id.content_view)
|
||||
View mView;
|
||||
private String mName;
|
||||
private File mFile;
|
||||
private EditorDelegate mEditorDelegate;
|
||||
private SparseArray<ToolbarMenuItem> mMenuMap;
|
||||
private EditorDelegate mEditorDelegate;
|
||||
private File mFile;
|
||||
private boolean mReadOnly = false;
|
||||
private OnActivityResultDelegate.Mediator mActivityResultMediator = new OnActivityResultDelegate.Mediator();
|
||||
private BroadcastReceiver mOnRunFinishedReceiver = new BroadcastReceiver() {
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.stardust.scriptdroid.ui.edit;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.AttrRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.jecelyin.editor.v2.common.Command;
|
||||
import com.jecelyin.editor.v2.core.widget.TextView;
|
||||
import com.jecelyin.editor.v2.ui.EditorDelegate;
|
||||
import com.jecelyin.editor.v2.view.EditorView;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.ui.edit.completion.InputMethodEnhanceBar;
|
||||
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Utils;
|
||||
|
||||
import org.androidannotations.annotations.EViewGroup;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/8/21.
|
||||
*/
|
||||
@EViewGroup(R.layout.script_edit_view)
|
||||
public class ScriptEditView extends FrameLayout {
|
||||
|
||||
private class InputMethodEnhanceBarBridge implements InputMethodEnhanceBar.EditTextBridge {
|
||||
|
||||
private TextView mTextView;
|
||||
|
||||
public InputMethodEnhanceBarBridge(TextView textView) {
|
||||
mTextView = textView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendText(CharSequence text) {
|
||||
insertText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void backspace(int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextView getEditText() {
|
||||
return mTextView;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private EditorDelegate mEditorDelegate;
|
||||
private File mFile;
|
||||
private boolean mReadOnly = false;
|
||||
|
||||
public ScriptEditView(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ScriptEditView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public ScriptEditView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return mReadOnly;
|
||||
}
|
||||
|
||||
public void setReadOnly(boolean readOnly) {
|
||||
mReadOnly = readOnly;
|
||||
}
|
||||
|
||||
public void setFile(File file) {
|
||||
mFile = file;
|
||||
mEditorDelegate = new EditorDelegate(0, mFile, 0, "utf-8");
|
||||
setUpEditor();
|
||||
}
|
||||
|
||||
public void setContent(String name, String str) {
|
||||
mEditorDelegate = new EditorDelegate(0, name, str);
|
||||
|
||||
}
|
||||
|
||||
public void insertText(CharSequence text) {
|
||||
Command c = new Command(Command.CommandEnum.INSERT_TEXT);
|
||||
c.object = text;
|
||||
mEditorDelegate.doCommand(c);
|
||||
}
|
||||
|
||||
private void setUpEditor() {
|
||||
final EditorView editorView = (EditorView) findViewById(R.id.editor);
|
||||
mEditorDelegate.setEditorView(editorView);
|
||||
if (mFile == null)
|
||||
Editor920Utils.setLang(mEditorDelegate, "JavaScript");
|
||||
editorView.getEditText().setReadOnly(mReadOnly);
|
||||
editorView.getEditText().setHorizontallyScrolling(true);
|
||||
setUpInputMethodEnhanceBar(editorView);
|
||||
}
|
||||
|
||||
|
||||
private void setUpInputMethodEnhanceBar(final EditorView editorView) {
|
||||
InputMethodEnhanceBar inputMethodEnhanceBar = (InputMethodEnhanceBar) findViewById(R.id.input_method_enhance_bar);
|
||||
if (mReadOnly) {
|
||||
inputMethodEnhanceBar.setVisibility(View.GONE);
|
||||
} else {
|
||||
inputMethodEnhanceBar.setEditTextBridge(new InputMethodEnhanceBarBridge(editorView.getEditText()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -32,6 +32,9 @@ import com.stardust.scriptdroid.external.floatingwindow.HoverMenuManger;
|
||||
import com.stardust.scriptdroid.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.scriptdroid.ui.main.community.CommunityFragment;
|
||||
import com.stardust.scriptdroid.ui.main.doc.OnlineDocsFragment;
|
||||
import com.stardust.scriptdroid.ui.main.doc.OnlineDocsFragment_;
|
||||
import com.stardust.scriptdroid.ui.main.script_list.MyScriptListFragment_;
|
||||
import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment_;
|
||||
import com.stardust.util.DeveloperUtils;
|
||||
@@ -62,17 +65,6 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
public static final String MESSAGE_CLEAR_BACKGROUND_SETTINGS = "MESSAGE_CLEAR_BACKGROUND_SETTINGS";
|
||||
|
||||
private static final String LOG_TAG = "MainActivity";
|
||||
private static final String EXTRA_ACTION = "EXTRA_ACTION";
|
||||
|
||||
private static final String ACTION_ON_RECORD_STOP = "ACTION_ON_RECORD_STOP";
|
||||
private static final String ACTION_IMPORT_SCRIPT = "ACTION_IMPORT_SCRIPT";
|
||||
private static final String ARGUMENT_SCRIPT = "ARGUMENT_SCRIPT";
|
||||
private static final String ARGUMENT_PATH = "ARGUMENT_PATH";
|
||||
private static final String ACTION_IMPORT_SAMPLE = "I cannot find the way back to you...Eating...17.4.29";
|
||||
private static final String ARGUMENT_SAMPLE = "Take a chance on me...ok...?";
|
||||
private static final String ARGUMENT_INPUT_STREAM = "17.7.12, Hi...could we start all over again...";
|
||||
private static final String ACTION_ON_ROOT_RECORD_STOP = "ACTION_ON_ROOT_RECORD_STOP";
|
||||
|
||||
|
||||
@ViewById(R.id.drawer_layout)
|
||||
DrawerLayout mDrawerLayout;
|
||||
@@ -183,9 +175,10 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
private void setUpTabViewPager() {
|
||||
TabLayout tabLayout = $(R.id.tab);
|
||||
mPagerAdapter = new FragmentPagerAdapterBuilder(this)
|
||||
.add(new MyScriptListFragment_(), R.string.text_my_script)
|
||||
.add(new SampleScriptListFragment(), R.string.text_sample_script)
|
||||
.add(new TaskManagerFragment_(), R.string.text_task_manage)
|
||||
.add(new MyScriptListFragment_(), R.string.text_script)
|
||||
.add(new OnlineDocsFragment_(), R.string.text_tutorial)
|
||||
.add(new CommunityFragment(), R.string.text_community)
|
||||
.add(new TaskManagerFragment_(), R.string.text_manage)
|
||||
.build();
|
||||
mViewPager.setAdapter(mPagerAdapter);
|
||||
tabLayout.setupWithViewPager(mViewPager);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.stardust.scriptdroid.ui.main.community;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/8/22.
|
||||
*/
|
||||
|
||||
public class CommunityFragment extends Fragment {
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.stardust.scriptdroid.ui.main.doc;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.util.BackPressedHandler;
|
||||
import com.stardust.widget.EWebView;
|
||||
|
||||
import org.androidannotations.annotations.AfterViews;
|
||||
import org.androidannotations.annotations.EFragment;
|
||||
import org.androidannotations.annotations.ViewById;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/8/22.
|
||||
*/
|
||||
@EFragment(R.layout.fragment_online_docs)
|
||||
public class OnlineDocsFragment extends Fragment implements BackPressedHandler {
|
||||
|
||||
@ViewById(R.id.eweb_view)
|
||||
EWebView mEWebView;
|
||||
WebView mWebView;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
((BackPressedHandler.HostActivity) getActivity())
|
||||
.getBackPressedObserver()
|
||||
.registerHandler(this);
|
||||
}
|
||||
|
||||
@AfterViews
|
||||
void setUpViews() {
|
||||
mWebView = mEWebView.getWebView();
|
||||
mWebView.loadUrl("https://hyb1996.github.io/AutoJs-Docs/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
((BackPressedHandler.HostActivity) getActivity())
|
||||
.getBackPressedObserver()
|
||||
.unregisterHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed(Activity activity) {
|
||||
if (mWebView.canGoBack()) {
|
||||
mWebView.goBack();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,19 @@
|
||||
package com.stardust.scriptdroid.ui.main.script_list;
|
||||
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.scriptdroid.script.ScriptFile;
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.script.Scripts;
|
||||
import com.stardust.scriptdroid.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.tool.SimpleObserver;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
|
||||
import com.stardust.widget.AutoAdapter;
|
||||
import com.stardust.widget.BindableViewHolder;
|
||||
import com.stardust.widget.ViewHolderSupplier;
|
||||
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
|
||||
import com.stardust.scriptdroid.ui.edit.ScriptEditView;
|
||||
|
||||
import org.androidannotations.annotations.AfterViews;
|
||||
import org.androidannotations.annotations.EFragment;
|
||||
@@ -32,22 +21,11 @@ import org.androidannotations.annotations.ViewById;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.reactivestreams.Subscriber;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Optional;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Observer;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.functions.Predicate;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
@@ -56,76 +34,18 @@ import io.reactivex.schedulers.Schedulers;
|
||||
@EFragment(R.layout.fragment_my_script_list)
|
||||
public class MyScriptListFragment extends Fragment {
|
||||
|
||||
public static final String MESSAGE_SCRIPT_FILE_ADDED = "MESSAGE_SCRIPT_FILE_ADDED";
|
||||
|
||||
private static final String TAG = "MyScriptListFragment";
|
||||
|
||||
private static ScriptFile sCurrentDirectory = StorageFileProvider.DEFAULT_DIRECTORY;
|
||||
|
||||
@ViewById(R.id.script_file_list)
|
||||
RecyclerView mScriptFileList;
|
||||
ScriptListView mScriptFileList;
|
||||
|
||||
@ViewById(R.id.swipe_refresh_layout)
|
||||
SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
|
||||
private ScriptListAdapter mScriptListAdapter = new ScriptListAdapter();
|
||||
private ScriptFile mSelectedScriptFile;
|
||||
|
||||
private ArrayList<ScriptFile> mScriptFiles = new ArrayList<>();
|
||||
private ArrayList<ScriptFile> mDirectories = new ArrayList<>();
|
||||
|
||||
@AfterViews
|
||||
void setUpViews() {
|
||||
initScriptListRecyclerView();
|
||||
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
loadScriptList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initScriptListRecyclerView() {
|
||||
mScriptFileList.setAdapter(mScriptListAdapter);
|
||||
GridLayoutManager manager = new GridLayoutManager(getContext(), 2);
|
||||
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
|
||||
@Override
|
||||
public int getSpanSize(int position) {
|
||||
//For directories
|
||||
if (position >= 1 && position <= mDirectories.size()) {
|
||||
return 1;
|
||||
}
|
||||
//For files and category
|
||||
return 2;
|
||||
}
|
||||
});
|
||||
mScriptFileList.setLayoutManager(manager);
|
||||
loadScriptList();
|
||||
}
|
||||
|
||||
private void loadScriptList() {
|
||||
mScriptFiles.clear();
|
||||
mDirectories.clear();
|
||||
StorageFileProvider.getDefault().getInitialDirectoryScriptFiles()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new SimpleObserver<ScriptFile>() {
|
||||
|
||||
@Override
|
||||
public void onNext(@io.reactivex.annotations.NonNull ScriptFile file) {
|
||||
if (file.isFile()) {
|
||||
mScriptFiles.add(file);
|
||||
} else {
|
||||
mDirectories.add(file);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
mScriptListAdapter.notifyDataSetChanged();
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -165,12 +85,7 @@ public class MyScriptListFragment extends Fragment {
|
||||
|
||||
private void onScriptFileOperated() {
|
||||
mSelectedScriptFile = null;
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Optional
|
||||
@@ -224,123 +139,5 @@ public class MyScriptListFragment extends Fragment {
|
||||
});
|
||||
}
|
||||
|
||||
private class ScriptListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private final int VIEW_TYPE_FILE = 0;
|
||||
private final int VIEW_TYPE_DIRECTORY = 1;
|
||||
//category是类别,也即"文件", "文件夹"那两个
|
||||
private final int VIEW_TYPE_CATEGORY = 2;
|
||||
|
||||
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
if (viewType == VIEW_TYPE_FILE) {
|
||||
return new ScriptFileViewHolder(inflater.inflate(R.layout.script_file_list_file, parent, false));
|
||||
} else if (viewType == VIEW_TYPE_DIRECTORY) {
|
||||
return new DirectoryViewHolder(inflater.inflate(R.layout.script_file_list_directory, parent, false));
|
||||
} else {
|
||||
return new CategoryViewHolder(inflater.inflate(R.layout.script_file_list_category, parent, false));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
||||
BindableViewHolder bindableViewHolder = (BindableViewHolder) holder;
|
||||
if (position == 0 || position == mDirectories.size() + 1) {
|
||||
bindableViewHolder.bind(position == 0, position);
|
||||
return;
|
||||
}
|
||||
if (position <= mDirectories.size()) {
|
||||
bindableViewHolder.bind(mDirectories.get(position - 1), position);
|
||||
return;
|
||||
}
|
||||
bindableViewHolder.bind(mScriptFiles.get(position - mDirectories.size() - 2), position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == 0 || position == mDirectories.size() + 1) {
|
||||
return VIEW_TYPE_CATEGORY;
|
||||
}
|
||||
if (position <= mDirectories.size()) {
|
||||
return VIEW_TYPE_DIRECTORY;
|
||||
}
|
||||
return VIEW_TYPE_FILE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mScriptFiles.size() + mDirectories.size() + 2;
|
||||
}
|
||||
}
|
||||
|
||||
static class ScriptFileViewHolder extends BindableViewHolder<ScriptFile> {
|
||||
|
||||
private static final DateFormat DATE_FORMAT = SimpleDateFormat.getDateTimeInstance();
|
||||
|
||||
@BindView(R.id.name)
|
||||
TextView mName;
|
||||
@BindView(R.id.first_char)
|
||||
TextView mFirstChar;
|
||||
@BindView(R.id.desc)
|
||||
TextView mDesc;
|
||||
GradientDrawable mFirstCharBackground;
|
||||
|
||||
public ScriptFileViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
mFirstCharBackground = (GradientDrawable) mFirstChar.getBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(ScriptFile file, int position) {
|
||||
mName.setText(file.getSimplifiedName());
|
||||
mDesc.setText(PFile.getHumanReadableSize(file.length()));
|
||||
if (file.getType() == ScriptFile.TYPE_JAVA_SCRIPT) {
|
||||
mFirstChar.setText("J");
|
||||
//什么?裸写颜色代码?!不影响代码可读性和重构成本的情况下,这样子修改起来方便多啦
|
||||
mFirstCharBackground.setColor(0xFF99CC99);
|
||||
} else {
|
||||
mFirstChar.setText("R");
|
||||
mFirstCharBackground.setColor(0xFFFD999A);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class DirectoryViewHolder extends BindableViewHolder<ScriptFile> {
|
||||
|
||||
@BindView(R.id.name)
|
||||
TextView mName;
|
||||
|
||||
public DirectoryViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(ScriptFile data, int position) {
|
||||
mName.setText(data.getSimplifiedName());
|
||||
}
|
||||
}
|
||||
|
||||
static class CategoryViewHolder extends BindableViewHolder<Boolean> {
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView mTitle;
|
||||
|
||||
public CategoryViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(Boolean isDirCategory, int position) {
|
||||
mTitle.setText(isDirCategory ? R.string.text_directory : R.string.text_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
package com.stardust.scriptdroid.ui.main.script_list;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.script.Scripts;
|
||||
import com.stardust.scriptdroid.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.tool.SimpleObserver;
|
||||
import com.stardust.widget.BindableViewHolder;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/8/21.
|
||||
*/
|
||||
|
||||
public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLayout.OnRefreshListener {
|
||||
|
||||
public interface OnScriptFileClickListener {
|
||||
void onScriptFileClick(View view, ScriptFile file);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
public ScriptListView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ScriptListView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ScriptFile getCurrentDirectory() {
|
||||
return mCurrentDirectory;
|
||||
}
|
||||
|
||||
public void setCurrentDirectory(ScriptFile currentDirectory) {
|
||||
mCurrentDirectory = currentDirectory;
|
||||
loadScriptList();
|
||||
}
|
||||
|
||||
public void setOnScriptFileClickListener(OnScriptFileClickListener onScriptFileClickListener) {
|
||||
mOnScriptFileClickListener = onScriptFileClickListener;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setOnRefreshListener(this);
|
||||
mScriptListView = new RecyclerView(getContext());
|
||||
addView(mScriptListView);
|
||||
initScriptListRecyclerView();
|
||||
setCurrentDirectory(StorageFileProvider.getDefault().getInitialDirectory());
|
||||
}
|
||||
|
||||
private void initScriptListRecyclerView() {
|
||||
mScriptListView.setAdapter(mScriptListAdapter);
|
||||
GridLayoutManager manager = new GridLayoutManager(getContext(), 2);
|
||||
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
|
||||
@Override
|
||||
public int getSpanSize(int position) {
|
||||
//For directories
|
||||
if (position >= 1 && position <= mDirectories.size()) {
|
||||
return 1;
|
||||
}
|
||||
//For files and category
|
||||
return 2;
|
||||
}
|
||||
});
|
||||
mScriptListView.setLayoutManager(manager);
|
||||
}
|
||||
|
||||
|
||||
private void loadScriptList() {
|
||||
mScriptFiles.clear();
|
||||
mDirectories.clear();
|
||||
StorageFileProvider.getDefault().getDirectoryScriptFiles(mCurrentDirectory)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new SimpleObserver<ScriptFile>() {
|
||||
|
||||
@Override
|
||||
public void onNext(@io.reactivex.annotations.NonNull ScriptFile file) {
|
||||
if (file.isFile()) {
|
||||
mScriptFiles.add(file);
|
||||
} else {
|
||||
mDirectories.add(file);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
mScriptListAdapter.notifyDataSetChanged();
|
||||
setRefreshing(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
loadScriptList();
|
||||
}
|
||||
|
||||
private class ScriptListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private final int VIEW_TYPE_FILE = 0;
|
||||
private final int VIEW_TYPE_DIRECTORY = 1;
|
||||
//category是类别,也即"文件", "文件夹"那两个
|
||||
private final int VIEW_TYPE_CATEGORY = 2;
|
||||
|
||||
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
if (viewType == VIEW_TYPE_FILE) {
|
||||
return new ScriptFileViewHolder(inflater.inflate(R.layout.script_file_list_file, parent, false));
|
||||
} else if (viewType == VIEW_TYPE_DIRECTORY) {
|
||||
return new DirectoryViewHolder(inflater.inflate(R.layout.script_file_list_directory, parent, false));
|
||||
} else {
|
||||
return new CategoryViewHolder(inflater.inflate(R.layout.script_file_list_category, parent, false));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
||||
BindableViewHolder bindableViewHolder = (BindableViewHolder) holder;
|
||||
if (position == 0 || position == mDirectories.size() + 1) {
|
||||
bindableViewHolder.bind(position == 0, position);
|
||||
return;
|
||||
}
|
||||
if (position <= mDirectories.size()) {
|
||||
bindableViewHolder.bind(mDirectories.get(position - 1), position);
|
||||
return;
|
||||
}
|
||||
bindableViewHolder.bind(mScriptFiles.get(position - mDirectories.size() - 2), position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == 0 || position == mDirectories.size() + 1) {
|
||||
return VIEW_TYPE_CATEGORY;
|
||||
}
|
||||
if (position <= mDirectories.size()) {
|
||||
return VIEW_TYPE_DIRECTORY;
|
||||
}
|
||||
return VIEW_TYPE_FILE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mScriptFiles.size() + mDirectories.size() + 2;
|
||||
}
|
||||
}
|
||||
|
||||
class ScriptFileViewHolder extends BindableViewHolder<ScriptFile> {
|
||||
|
||||
|
||||
@BindView(R.id.name)
|
||||
TextView mName;
|
||||
@BindView(R.id.first_char)
|
||||
TextView mFirstChar;
|
||||
@BindView(R.id.desc)
|
||||
TextView mDesc;
|
||||
GradientDrawable mFirstCharBackground;
|
||||
private ScriptFile mScriptFile;
|
||||
|
||||
ScriptFileViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
mFirstCharBackground = (GradientDrawable) mFirstChar.getBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(ScriptFile file, int position) {
|
||||
mScriptFile = file;
|
||||
mName.setText(file.getSimplifiedName());
|
||||
mDesc.setText(PFile.getHumanReadableSize(file.length()));
|
||||
if (file.getType() == ScriptFile.TYPE_JAVA_SCRIPT) {
|
||||
mFirstChar.setText("J");
|
||||
//什么?裸写颜色代码?!不影响代码可读性和重构成本的情况下,这样子修改起来方便多啦
|
||||
mFirstCharBackground.setColor(0xFF99CC99);
|
||||
} else {
|
||||
mFirstChar.setText("R");
|
||||
mFirstCharBackground.setColor(0xFFFD999A);
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.item)
|
||||
void onItemClick() {
|
||||
if(mOnScriptFileClickListener != null){
|
||||
mOnScriptFileClickListener.onScriptFileClick(itemView, mScriptFile);
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.run)
|
||||
void run() {
|
||||
Scripts.run(mScriptFile);
|
||||
}
|
||||
|
||||
@OnClick(R.id.edit)
|
||||
void edit() {
|
||||
Scripts.edit(mScriptFile);
|
||||
}
|
||||
|
||||
@OnClick(R.id.more)
|
||||
void showOptionMenu() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class DirectoryViewHolder extends BindableViewHolder<ScriptFile> {
|
||||
|
||||
@BindView(R.id.name)
|
||||
TextView mName;
|
||||
private ScriptFile mScriptFile;
|
||||
|
||||
DirectoryViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(ScriptFile data, int position) {
|
||||
mName.setText(data.getSimplifiedName());
|
||||
mScriptFile = data;
|
||||
}
|
||||
|
||||
@OnClick(R.id.item)
|
||||
void onItemClick() {
|
||||
setCurrentDirectory(mScriptFile);
|
||||
}
|
||||
|
||||
@OnClick(R.id.more)
|
||||
void showOptionMenu() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class CategoryViewHolder extends BindableViewHolder<Boolean> {
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView mTitle;
|
||||
|
||||
CategoryViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(Boolean isDirCategory, int position) {
|
||||
mTitle.setText(isDirCategory ? R.string.text_directory : R.string.text_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.stardust.widget;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.Window;
|
||||
|
||||
import com.stardust.util.ViewUtil;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/8/22.
|
||||
*/
|
||||
|
||||
public class AppWithStatusBarLayout extends AppBarLayout {
|
||||
|
||||
public AppWithStatusBarLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public AppWithStatusBarLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onWindowVisibilityChanged(int visibility) {
|
||||
super.onWindowVisibilityChanged(visibility);
|
||||
if (visibility == VISIBLE) {
|
||||
setPadding();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
setPadding();
|
||||
}
|
||||
|
||||
private void setPadding() {
|
||||
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
setPadding(getPaddingLeft(), getStatusBarHeight(), getPaddingRight(), getPaddingBottom());
|
||||
getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private int getStatusBarHeight() {
|
||||
Rect rect = new Rect();
|
||||
Window window = getWindow();
|
||||
if (window == null) {
|
||||
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics());
|
||||
}
|
||||
window.getDecorView().getWindowVisibleDisplayFrame(rect);
|
||||
return rect.top;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private Window getWindow() {
|
||||
return getWindowForContext(getContext());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Window getWindowForContext(Context context) {
|
||||
if (context instanceof Activity) {
|
||||
return ((Activity) context).getWindow();
|
||||
}
|
||||
if (context instanceof ContextWrapper) {
|
||||
return getWindowForContext(((ContextWrapper) context).getBaseContext());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
109
app/src/main/java/com/stardust/widget/EWebView.java
Normal file
109
app/src/main/java/com/stardust/widget/EWebView.java
Normal file
@@ -0,0 +1,109 @@
|
||||
package com.stardust.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.util.AttributeSet;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.stardust.scriptdroid.R;
|
||||
|
||||
import org.androidannotations.annotations.ViewById;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/8/22.
|
||||
*/
|
||||
|
||||
public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefreshListener {
|
||||
|
||||
private WebView mWebView;
|
||||
private ProgressBar mProgressBar;
|
||||
SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
|
||||
public EWebView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public EWebView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.ewebview, this);
|
||||
mWebView = (WebView) findViewById(R.id.web_view);
|
||||
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
|
||||
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
|
||||
mSwipeRefreshLayout.setOnRefreshListener(this);
|
||||
setUpWebView();
|
||||
}
|
||||
|
||||
private void setUpWebView() {
|
||||
WebSettings settings = mWebView.getSettings();
|
||||
settings.setUseWideViewPort(true);
|
||||
settings.setBuiltInZoomControls(true);
|
||||
settings.setSupportZoom(true);
|
||||
settings.setLoadWithOverviewMode(true);
|
||||
settings.setJavaScriptEnabled(true);
|
||||
mWebView.setWebViewClient(new MyWebViewClient());
|
||||
mWebView.setWebChromeClient(new MyWebChromeClient());
|
||||
}
|
||||
|
||||
public WebView getWebView() {
|
||||
return mWebView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
mWebView.reload();
|
||||
}
|
||||
|
||||
private class MyWebChromeClient extends WebChromeClient {
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(WebView view, int newProgress) {
|
||||
super.onProgressChanged(view, newProgress);
|
||||
mProgressBar.setProgress(newProgress);
|
||||
}
|
||||
}
|
||||
|
||||
private class MyWebViewClient extends WebViewClient {
|
||||
|
||||
@Override
|
||||
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
||||
super.onPageStarted(view, url, favicon);
|
||||
mProgressBar.setProgress(0);
|
||||
mProgressBar.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
super.onPageFinished(view, url);
|
||||
mProgressBar.setVisibility(GONE);
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
||||
view.loadUrl(request.getUrl().toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||
view.loadUrl(url);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user