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"
minSdkVersion 17
targetSdkVersion 23
versionCode 201
versionName "3.0.0 Alpha2"
versionCode 202
versionName "3.0.0 Alpha3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {

View File

@ -55,7 +55,7 @@ public class ScriptOperations {
}
public ScriptOperations(Context context, View view) {
this(context, view, MyScriptListFragment.getCurrentDirectory());
this(context, view, StorageFileProvider.DEFAULT_DIRECTORY);
}
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) {
((ViewPagerFragment) fragment).setFab(mFab);
if (pos == mViewPager.getCurrentItem()) {
((ViewPagerFragment) fragment).onPageSelected();
((ViewPagerFragment) fragment).onPageShow();
}
}
});
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
private ViewPagerFragment mPreviousFragment;
@Override
public void onPageSelected(int position) {
Fragment fragment = mPagerAdapter.getStoredFragment(position);
if (fragment == null)
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);
public void onPageSelected() {
public void onPageShow() {
if (mFabRotation == ROTATION_GONE) {
if (mFab.getVisibility() == View.VISIBLE) {
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
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
if(isHidden()){
return;
}
Toast.makeText(App.getApp(), e.getMessage(), Toast.LENGTH_SHORT).show();
mConnectionItem.getSwitchCompat().setChecked(false, false);
mConnectionItem.setProgress(false);

View File

@ -1,5 +1,6 @@
package com.stardust.scriptdroid.ui.main.scripts;
import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
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.Scripts;
import com.stardust.scriptdroid.script.StorageFileProvider;
import com.stardust.scriptdroid.tool.SimpleObserver;
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.util.BackPressedHandler;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EFragment;
@ -26,6 +30,7 @@ import butterknife.OnClick;
import butterknife.Optional;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
@ -33,12 +38,10 @@ import io.reactivex.schedulers.Schedulers;
* Created by Stardust on 2017/3/13.
*/
@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 ScriptFile sCurrentDirectory = StorageFileProvider.DEFAULT_DIRECTORY;
public MyScriptListFragment() {
super(0);
}
@ -46,6 +49,8 @@ public class MyScriptListFragment extends ViewPagerFragment {
@ViewById(R.id.script_file_list)
ScriptListView mScriptFileList;
private FloatingActionMenu mFloatingActionMenu;
@AfterViews
void setUpViews() {
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() {
return sCurrentDirectory;
@Override
public void onPause() {
super.onPause();
((BackPressedHandler.HostActivity) getActivity())
.getBackPressedObserver()
.unregisterHandler(this);
}
@Override
protected void onFabClick(FloatingActionButton fab) {
new NewFileDialogBuilder(getContext())
.show();
initFloatingActionMenuIfNeeded(fab);
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"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<com.stardust.theme.widget.ThemeColorFloatingActionButton
android:id="@+id/fab"
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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_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>

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:checked="true"
android:paddingLeft="16dp"
android:button="@null"
android:text="@string/text_file"
android:textSize="16sp"/>

View File

@ -236,7 +236,7 @@
<string name="not_login">未登录</string>
<string name="text_volume_down_control">音量下键控制</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_ui_mode">ui模式</string>
<string name="text_new">新建</string>