new ui for NewFileDialog (change to FloatingActionsMenu)

This commit is contained in:
hyb1996
2017-09-25 13:40:34 +08:00
parent 8c9777c138
commit b9f8f9bbd7
16 changed files with 318 additions and 85 deletions

View File

@@ -9,8 +9,8 @@ android {
applicationId "com.stardust.scriptdroid" applicationId "com.stardust.scriptdroid"
minSdkVersion 17 minSdkVersion 17
targetSdkVersion 23 targetSdkVersion 23
versionCode 201 versionCode 202
versionName "3.0.0 Alpha2" versionName "3.0.0 Alpha3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
ndk { ndk {

View File

@@ -55,7 +55,7 @@ public class ScriptOperations {
} }
public ScriptOperations(Context context, View view) { public ScriptOperations(Context context, View view) {
this(context, view, MyScriptListFragment.getCurrentDirectory()); this(context, view, StorageFileProvider.DEFAULT_DIRECTORY);
} }
public void newScriptFileForScript(final String script) { public void newScriptFileForScript(final String script) {

View File

@@ -0,0 +1,153 @@
package com.stardust.scriptdroid.ui.main;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;
/**
* Created by Stardust on 2017/9/24.
*/
public class FloatingActionMenu extends FrameLayout implements View.OnClickListener {
public interface OnFloatingActionButtonClickListener {
void onClick(FloatingActionButton button, int pos);
}
private static final int[] ICONS = {
R.drawable.ic_floating_action_menu_dir,
R.drawable.ic_floating_action_menu_file,
R.drawable.ic_floating_action_menu_open};
private static final int[] LABELS = {R.string.text_directory, R.string.text_file, R.string.text_import};
private TextView[] mLabels;
private FloatingActionButton[] mFabs;
private View[] mFabContainers;
private boolean mExpanded = false;
private int mInterval = 30;
private int mDuration = 300;
private final Interpolator mInterpolator = new FastOutSlowInInterpolator();
private final PublishSubject<Boolean> mState = PublishSubject.create();
private OnFloatingActionButtonClickListener mOnFloatingActionButtonClickListener;
public FloatingActionMenu(@NonNull Context context) {
super(context);
init();
}
public FloatingActionMenu(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public FloatingActionMenu(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
buildFabs(ICONS, LABELS);
}
public boolean isExpanded() {
return mExpanded;
}
public void expand() {
setVisibility(VISIBLE);
int h = mFabs[0].getHeight();
for (int i = 0; i < mFabContainers.length; i++) {
animateY(mFabContainers[i], -(h + mInterval) * (i + 1), null);
}
mExpanded = true;
mState.onNext(true);
}
private void animateY(View view, float y, Animator.AnimatorListener l) {
view.animate()
.translationY(y)
.setDuration(mDuration)
.setInterpolator(mInterpolator)
.setListener(l)
.start();
}
public void collapse() {
animateY(mFabContainers[0], 0, new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
setVisibility(INVISIBLE);
}
});
for (int i = 1; i < mFabContainers.length; i++) {
animateY(mFabContainers[i], 0, null);
}
mExpanded = false;
mState.onNext(false);
}
private void buildFabs(int[] icons, int[] labels) {
if (icons.length != labels.length)
throw new IllegalArgumentException("icons.length = " + icons.length + " is not equal to labels.length = " + labels.length);
mFabs = new FloatingActionButton[icons.length];
mLabels = new TextView[icons.length];
mFabContainers = new View[icons.length];
LayoutInflater inflater = LayoutInflater.from(getContext());
for (int i = 0; i < icons.length; i++) {
mFabContainers[i] = inflater.inflate(R.layout.item_floating_action_menu, this, false);
mFabs[i] = (FloatingActionButton) mFabContainers[i].findViewById(R.id.floating_action_button);
mFabs[i].setImageResource(icons[i]);
mFabs[i].setOnClickListener(this);
mFabs[i].setTag(i);
mLabels[i] = (TextView) mFabContainers[i].findViewById(R.id.label);
mLabels[i].setText(labels[i]);
addView(mFabContainers[i]);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
// Call super.onMeasure to measure children and width
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (heightMode == MeasureSpec.EXACTLY) {
return;
}
int h = mFabContainers[0].getMeasuredHeight();
setMeasuredDimension(getMeasuredWidth(), (h + mInterval) * mFabs.length + h);
}
public PublishSubject<Boolean> getState() {
return mState;
}
@Override
public void onClick(View v) {
collapse();
if (mOnFloatingActionButtonClickListener != null) {
mOnFloatingActionButtonClickListener.onClick((FloatingActionButton) v, (int) v.getTag());
}
}
public void setOnFloatingActionButtonClickListener(OnFloatingActionButtonClickListener onFloatingActionButtonClickListener) {
mOnFloatingActionButtonClickListener = onFloatingActionButtonClickListener;
}
}

View File

@@ -154,17 +154,23 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
public void OnInstantiate(int pos, Fragment fragment) { public void OnInstantiate(int pos, Fragment fragment) {
((ViewPagerFragment) fragment).setFab(mFab); ((ViewPagerFragment) fragment).setFab(mFab);
if (pos == mViewPager.getCurrentItem()) { if (pos == mViewPager.getCurrentItem()) {
((ViewPagerFragment) fragment).onPageSelected(); ((ViewPagerFragment) fragment).onPageShow();
} }
} }
}); });
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
private ViewPagerFragment mPreviousFragment;
@Override @Override
public void onPageSelected(int position) { public void onPageSelected(int position) {
Fragment fragment = mPagerAdapter.getStoredFragment(position); Fragment fragment = mPagerAdapter.getStoredFragment(position);
if (fragment == null) if (fragment == null)
return; return;
((ViewPagerFragment) fragment).onPageSelected(); if (mPreviousFragment != null) {
mPreviousFragment.onPageHide();
}
mPreviousFragment = (ViewPagerFragment) fragment;
mPreviousFragment.onPageShow();
} }
}); });
} }

View File

@@ -1,64 +0,0 @@
package com.stardust.scriptdroid.ui.main;
import android.content.Context;
import android.view.View;
import com.github.aakira.expandablelayout.ExpandableRelativeLayout;
import com.stardust.scriptdroid.R;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
* Created by Stardust on 2017/8/25.
*/
public class NewFileDialogBuilder extends ThemeColorMaterialDialogBuilder {
@BindView(R.id.layout_new_file)
ExpandableRelativeLayout mLayoutNewFile;
@BindView(R.id.layout_import)
ExpandableRelativeLayout mLayoutImport;
ExpandableRelativeLayout mExpandedLayout;
public NewFileDialogBuilder(Context context) {
super(context);
View view = View.inflate(context, R.layout.new_file_dialog, null);
customView(view, true);
title(R.string.text_new);
positiveText(R.string.ok);
negativeText(R.string.cancel);
ButterKnife.bind(this, view);
mExpandedLayout = mLayoutNewFile;
}
@OnClick(R.id.option_new_file)
void expandLayoutNewFile() {
if (mExpandedLayout != mLayoutNewFile) {
if(mExpandedLayout != null){
mExpandedLayout.collapse();
}
mLayoutNewFile.expand();
mExpandedLayout = mLayoutNewFile;
}
}
@OnClick(R.id.option_import)
void expandLayoutImport() {
if (mExpandedLayout != mLayoutImport) {
if(mExpandedLayout != null){
mExpandedLayout.collapse();
}
mLayoutImport.expand();
mExpandedLayout = mLayoutImport;
}
}
}

View File

@@ -32,7 +32,7 @@ public abstract class ViewPagerFragment extends Fragment {
protected abstract void onFabClick(FloatingActionButton fab); protected abstract void onFabClick(FloatingActionButton fab);
public void onPageSelected() { public void onPageShow() {
if (mFabRotation == ROTATION_GONE) { if (mFabRotation == ROTATION_GONE) {
if (mFab.getVisibility() == View.VISIBLE) { if (mFab.getVisibility() == View.VISIBLE) {
mFab.hide(); mFab.hide();
@@ -54,4 +54,7 @@ public abstract class ViewPagerFragment extends Fragment {
} }
public void onPageHide() {
}
} }

View File

@@ -244,6 +244,9 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
@Override @Override
public void onError(@io.reactivex.annotations.NonNull Throwable e) { public void onError(@io.reactivex.annotations.NonNull Throwable e) {
if(isHidden()){
return;
}
Toast.makeText(App.getApp(), e.getMessage(), Toast.LENGTH_SHORT).show(); Toast.makeText(App.getApp(), e.getMessage(), Toast.LENGTH_SHORT).show();
mConnectionItem.getSwitchCompat().setChecked(false, false); mConnectionItem.getSwitchCompat().setChecked(false, false);
mConnectionItem.setProgress(false); mConnectionItem.setProgress(false);

View File

@@ -1,5 +1,6 @@
package com.stardust.scriptdroid.ui.main.scripts; package com.stardust.scriptdroid.ui.main.scripts;
import android.app.Activity;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
@@ -12,9 +13,12 @@ import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.script.ScriptFile; import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.scriptdroid.script.Scripts; import com.stardust.scriptdroid.script.Scripts;
import com.stardust.scriptdroid.script.StorageFileProvider; 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.ScriptLoopDialog;
import com.stardust.scriptdroid.ui.main.NewFileDialogBuilder; import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.main.FloatingActionMenu;
import com.stardust.scriptdroid.ui.main.ViewPagerFragment; import com.stardust.scriptdroid.ui.main.ViewPagerFragment;
import com.stardust.util.BackPressedHandler;
import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EFragment; import org.androidannotations.annotations.EFragment;
@@ -26,6 +30,7 @@ import butterknife.OnClick;
import butterknife.Optional; import butterknife.Optional;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer; import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
@@ -33,12 +38,10 @@ import io.reactivex.schedulers.Schedulers;
* Created by Stardust on 2017/3/13. * Created by Stardust on 2017/3/13.
*/ */
@EFragment(R.layout.fragment_my_script_list) @EFragment(R.layout.fragment_my_script_list)
public class MyScriptListFragment extends ViewPagerFragment { public class MyScriptListFragment extends ViewPagerFragment implements BackPressedHandler, FloatingActionMenu.OnFloatingActionButtonClickListener {
private static final String TAG = "MyScriptListFragment"; private static final String TAG = "MyScriptListFragment";
private static ScriptFile sCurrentDirectory = StorageFileProvider.DEFAULT_DIRECTORY;
public MyScriptListFragment() { public MyScriptListFragment() {
super(0); super(0);
} }
@@ -46,6 +49,8 @@ public class MyScriptListFragment extends ViewPagerFragment {
@ViewById(R.id.script_file_list) @ViewById(R.id.script_file_list)
ScriptListView mScriptFileList; ScriptListView mScriptFileList;
private FloatingActionMenu mFloatingActionMenu;
@AfterViews @AfterViews
void setUpViews() { void setUpViews() {
mScriptFileList.setOnScriptFileClickListener(new ScriptListView.OnScriptFileClickListener() { mScriptFileList.setOnScriptFileClickListener(new ScriptListView.OnScriptFileClickListener() {
@@ -56,14 +61,87 @@ public class MyScriptListFragment extends ViewPagerFragment {
}); });
} }
@Override
public void onResume() {
super.onResume();
((BackPressedHandler.HostActivity) getActivity())
.getBackPressedObserver()
.registerHandlerAtFront(this);
}
public static ScriptFile getCurrentDirectory() { @Override
return sCurrentDirectory; public void onPause() {
super.onPause();
((BackPressedHandler.HostActivity) getActivity())
.getBackPressedObserver()
.unregisterHandler(this);
} }
@Override @Override
protected void onFabClick(FloatingActionButton fab) { protected void onFabClick(FloatingActionButton fab) {
new NewFileDialogBuilder(getContext()) initFloatingActionMenuIfNeeded(fab);
.show(); if (mFloatingActionMenu.isExpanded()) {
mFloatingActionMenu.collapse();
} else {
mFloatingActionMenu.expand();
}
}
private void initFloatingActionMenuIfNeeded(final FloatingActionButton fab) {
if (mFloatingActionMenu != null)
return;
mFloatingActionMenu = ((FloatingActionMenu) getActivity().findViewById(R.id.floating_action_menu));
mFloatingActionMenu.getState()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SimpleObserver<Boolean>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull Boolean expanding) {
fab.animate()
.rotation(expanding ? 45 : 0)
.setDuration(300)
.start();
}
});
mFloatingActionMenu.setOnFloatingActionButtonClickListener(this);
}
@Override
public boolean onBackPressed(Activity activity) {
if (mFloatingActionMenu != null && mFloatingActionMenu.isExpanded()) {
mFloatingActionMenu.expand();
return true;
}
return false;
}
@Override
public void onPageHide() {
if (mFloatingActionMenu != null && mFloatingActionMenu.isExpanded()) {
mFloatingActionMenu.collapse();
}
}
@Override
public void onDetach() {
super.onDetach();
mFloatingActionMenu.setOnFloatingActionButtonClickListener(null);
}
@Override
public void onClick(FloatingActionButton button, int pos) {
switch (pos) {
case 0:
new ScriptOperations(getContext(), mScriptFileList, mScriptFileList.getCurrentDirectory())
.newDirectory();
break;
case 1:
new ScriptOperations(getContext(), mScriptFileList, mScriptFileList.getCurrentDirectory())
.newScriptFile();
break;
case 2:
break;
}
} }
} }

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#cc424347"/>
<corners android:radius="2dp"/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -42,17 +42,31 @@
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/> app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<com.stardust.theme.widget.ThemeColorFloatingActionButton <FrameLayout
android:id="@+id/fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="16dp"
android:clickable="true"
android:src="@drawable/ic_add_white_48dp"
app:backgroundTint="@color/colorPrimary"
app:layout_anchor="@id/viewpager" app:layout_anchor="@id/viewpager"
app:layout_anchorGravity="bottom|right|end" app:layout_anchorGravity="bottom|right|end"
app:layout_behavior="com.stardust.widget.ScrollAwareFABBehavior"/> >
<com.stardust.scriptdroid.ui.main.FloatingActionMenu
android:id="@+id/floating_action_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end|bottom"
android:visibility="invisible"/>
<com.stardust.theme.widget.ThemeColorFloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end|bottom"
android:clickable="true"
android:src="@drawable/ic_add_white_48dp"
app:backgroundTint="@color/colorPrimary"
app:layout_behavior="com.stardust.widget.ScrollAwareFABBehavior"/>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout> </android.support.design.widget.CoordinatorLayout>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right|end"
android:gravity="end|right"
android:orientation="horizontal">
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="12dp"
android:background="@drawable/floating_action_menu_label_bg"
android:gravity="center_vertical"
android:paddingBottom="2dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingTop="2dp"
android:textColor="#f2f3f7"
tools:text="文件夹"/>
<com.stardust.theme.widget.ThemeColorFloatingActionButton
android:id="@+id/floating_action_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_floating_action_menu_dir"
android:tint="@android:color/white"/>
</LinearLayout>

View File

@@ -31,6 +31,7 @@
android:layout_marginTop="@dimen/air_baseline" android:layout_marginTop="@dimen/air_baseline"
android:checked="true" android:checked="true"
android:paddingLeft="16dp" android:paddingLeft="16dp"
android:button="@null"
android:text="@string/text_file" android:text="@string/text_file"
android:textSize="16sp"/> android:textSize="16sp"/>

View File

@@ -236,7 +236,7 @@
<string name="not_login">未登录</string> <string name="not_login">未登录</string>
<string name="text_volume_down_control">音量下键控制</string> <string name="text_volume_down_control">音量下键控制</string>
<string name="text_others">其他</string> <string name="text_others">其他</string>
<string name="text_import">导入</string> <string name="text_import">导入</string>
<string name="text_auto_mode">auto模式</string> <string name="text_auto_mode">auto模式</string>
<string name="text_ui_mode">ui模式</string> <string name="text_ui_mode">ui模式</string>
<string name="text_new">新建</string> <string name="text_new">新建</string>