.*<\/div>|<\/?[^>]*>/g, '').trim().length;
102 | },
103 | saveRange: function saveRange() {
104 | //保存节点位置
105 | var _self = this;
106 | var selection = window.getSelection();
107 | if (selection.rangeCount > 0) {
108 | var range = selection.getRangeAt(0);
109 | var startContainer = range.startContainer,
110 | startOffset = range.startOffset,
111 | endContainer = range.endContainer,
112 | endOffset = range.endOffset;
113 |
114 | _self.currentRange = {
115 | startContainer: startContainer,
116 | startOffset: startOffset,
117 | endContainer: endContainer,
118 | endOffset: endOffset
119 | };
120 | }
121 | },
122 | reduceRange: function reduceRange() {
123 | //还原节点位置
124 | var _self = this;
125 | var _self$currentRange = _self.currentRange,
126 | startContainer = _self$currentRange.startContainer,
127 | startOffset = _self$currentRange.startOffset,
128 | endContainer = _self$currentRange.endContainer,
129 | endOffset = _self$currentRange.endOffset;
130 |
131 | var range = document.createRange();
132 | var selection = window.getSelection();
133 | selection.removeAllRanges();
134 | range.setStart(startContainer, startOffset);
135 | range.setEnd(endContainer, endOffset);
136 | selection.addRange(range);
137 | },
138 | exec: function exec(command) {
139 | //执行指令
140 | var _self = this;
141 | if (_self.commandSet.indexOf(command) !== -1) {
142 | document.execCommand(command, false, null);
143 | } else {
144 | var value = '<' + command + '>';
145 | document.execCommand('formatBlock', false, value);
146 | }
147 | },
148 | getEditItem: function getEditItem(evt) {
149 | //通过点击时,去获得一个当前位置的所有状态
150 | var _self = this;
151 | var _self$schemeCache2 = _self.schemeCache,
152 | STATE_SCHEME = _self$schemeCache2.STATE_SCHEME,
153 | CHANGE_SCHEME = _self$schemeCache2.CHANGE_SCHEME,
154 | IMAGE_SCHEME = _self$schemeCache2.IMAGE_SCHEME;
155 |
156 | if (evt.target && evt.target.tagName === 'A') {
157 | _self.cache.currentLink = evt.target;
158 | var name = evt.target.innerText;
159 | var href = evt.target.getAttribute('href');
160 | window.location.href = CHANGE_SCHEME + encodeURI(name + '@_@' + href);
161 | } else {
162 | if (e.which == 8) {
163 | AndroidInterface.staticWords();
164 | }
165 | var items = [];
166 | _self.commandSet.forEach(function (item) {
167 | if (document.queryCommandState(item)) {
168 | items.push(item);
169 | }
170 | });
171 | if (document.queryCommandValue('formatBlock')) {
172 | items.push(document.queryCommandValue('formatBlock'));
173 | }
174 | window.location.href = STATE_SCHEME + encodeURI(items.join(','));
175 | }
176 | },
177 | insertHtml: function insertHtml(html) {
178 | var _self = this;
179 | document.execCommand('insertHtml', false, html);
180 | },
181 | insertLine: function insertLine() {
182 | var _self = this;
183 | var html = '
';
184 | _self.insertHtml(html);
185 | },
186 | insertLink: function insertLink(name, url) {
187 | var _self = this;
188 | var html = '
' + name + '';
189 | _self.insertHtml(html);
190 | },
191 | changeLink: function changeLink(name, url) {
192 | var _self = this;
193 | var current = _self.cache.currentLink;
194 | var len = name.length;
195 | current.innerText = name;
196 | current.setAttribute('href', url);
197 | var selection = window.getSelection();
198 | var range = selection.getRangeAt(0).cloneRange();
199 | var _self$currentRange2 = _self.currentRange,
200 | startContainer = _self$currentRange2.startContainer,
201 | endContainer = _self$currentRange2.endContainer;
202 |
203 | selection.removeAllRanges();
204 | range.setStart(startContainer, len);
205 | range.setEnd(endContainer, len);
206 | selection.addRange(range);
207 | },
208 | insertImage: function insertImage(url, id, width, height) {
209 | var _self = this;
210 | var newWidth = 0,
211 | newHeight = 0;
212 | var screenWidth = _self.setting.screenWidth;
213 |
214 | if (width > screenWidth) {
215 | newWidth = screenWidth;
216 | newHeight = height * newWidth / width;
217 | } else {
218 | newWidth = width;
219 | newHeight = height;
220 | }
221 | var image = '
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

\n\t\t\t\t\t
\u56FE\u7247\u4E0A\u4F20\u5931\u8D25\uFF0C\u8BF7\u70B9\u51FB\u91CD\u8BD5
\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t
';
222 | _self.insertHtml(image);
223 | var img = document.querySelector('img[data-id="' + id + '"]');
224 | var imgBlock = img.parentNode;
225 | imgBlock.contentEditable = false;
226 | imgBlock.addEventListener('click', function (e) {
227 | e.stopPropagation();
228 | var current = e.currentTarget;
229 | var img = current.querySelector('.images');
230 | var id = img.getAttribute('data-id');
231 | window.location.href = _self.schemeCache.STATE_SCHEME + encodeURI(id);
232 | }, false);
233 | _self.imageCache.set(id, imgBlock);
234 | },
235 | changeProcess: function changeProcess(id, process) {
236 | var _self = this;
237 | var imgBlock = _self.imageCache.get(id);
238 | var fill = imgBlock.querySelector('.fill');
239 | fill.style.width = process + '%';
240 | if (process == 100) {
241 | var cover = imgBlock.querySelector('.cover');
242 | var process = imgBlock.querySelector('.process');
243 | imgBlock.removeChild(cover);
244 | imgBlock.removeChild(process);
245 | }
246 | },
247 | removeImage: function removeImage(id) {
248 | var _self = this;
249 | var imgBlock = _self.imageCache.get(id);
250 | imgBlock.parentNode.removeChild(imgBlock);
251 | _self.imageCache.delete(id);
252 | },
253 | uploadFailure: function uploadFailure(id) {
254 | var _self = this;
255 | var imgBlock = _self.imageCache.get(id);
256 | var del = imgBlock.querySelector('.delete');
257 | del.style.display = 'block';
258 | console.log('uploadFailure');
259 | },
260 | uploadReload: function uploadReload(id) {
261 | var _self = this;
262 | var imgBlock = _self.imageCache.get(id);
263 | var del = imgBlock.querySelector('.delete');
264 | del.style.display = 'none';
265 | }
266 | };
267 |
268 | RE.init();
269 |
--------------------------------------------------------------------------------
/lubottommenu/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/lubottommenu/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "25.0.3"
6 |
7 | defaultConfig {
8 | minSdkVersion 15
9 | targetSdkVersion 25
10 | versionCode 1
11 | versionName "1.0"
12 |
13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14 |
15 | }
16 | buildTypes {
17 | release {
18 | minifyEnabled false
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 | }
23 |
24 | dependencies {
25 | compile fileTree(include: ['*.jar'], dir: 'libs')
26 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
27 | exclude group: 'com.android.support', module: 'support-annotations'
28 | })
29 | compile 'com.android.support:appcompat-v7:25.3.1'
30 | testCompile 'junit:junit:4.12'
31 | }
32 |
--------------------------------------------------------------------------------
/lubottommenu/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in E:\android_sdk_studio/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/lubottommenu/src/androidTest/java/com/lu/lubottommenu/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.lu.lubottommenu;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see
Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.lu.lubottommenu.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lubottommenu/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/lubottommenu/src/main/java/com/lu/lubottommenu/AnimatorUtil.java:
--------------------------------------------------------------------------------
1 | package com.lu.lubottommenu;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorListenerAdapter;
5 | import android.animation.LayoutTransition;
6 | import android.animation.ObjectAnimator;
7 | import android.animation.ValueAnimator;
8 | import android.os.Build;
9 | import android.support.annotation.RequiresApi;
10 | import android.transition.Transition;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 |
14 | /**
15 | *
16 | * Created by 陆正威 on 2017/9/13.
17 | */
18 |
19 | class AnimatorUtil {
20 | static void show(final LuBottomMenu luBottomMenu, final long duration){
21 |
22 | luBottomMenu.post(new Runnable() {
23 | @RequiresApi(api = Build.VERSION_CODES.KITKAT)
24 | @Override
25 | public void run() {
26 | final ViewGroup.MarginLayoutParams layoutParams= (ViewGroup.MarginLayoutParams) luBottomMenu.getLayoutParams();
27 | luBottomMenu.animate()
28 | .translationY(0)
29 | .setListener(new AnimatorListenerAdapter() {
30 | @Override
31 | public void onAnimationStart(Animator animation) {
32 | luBottomMenu.setVisibility(View.VISIBLE);
33 | luBottomMenu.setAlpha(0);
34 | }
35 | })
36 | .setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
37 | @Override
38 | public void onAnimationUpdate(ValueAnimator animation) {
39 | layoutParams.setMargins(layoutParams.leftMargin, (int) (-luBottomMenu.getTranslationY()),
40 | layoutParams.rightMargin,layoutParams.bottomMargin);
41 | luBottomMenu.requestLayout();
42 | }
43 | })
44 | .setDuration(duration)
45 | .alpha(1f).start();
46 | }
47 | });
48 |
49 | }
50 |
51 | static void hide(final LuBottomMenu luBottomMenu, final long duration){
52 | luBottomMenu.post(new Runnable() {
53 | @Override
54 | public void run() {
55 | luBottomMenu.animate()
56 | .setDuration(duration)
57 | .translationY(luBottomMenu.getHeight())
58 | .alpha(0f)
59 | .setListener(new AnimatorListenerAdapter() {
60 | @Override
61 | public void onAnimationEnd(Animator animation) {
62 | super.onAnimationEnd(animation);
63 | luBottomMenu.setVisibility(View.GONE);
64 | }
65 | }).start();
66 | }
67 | });
68 | }
69 |
70 | static void setTransition(ViewGroup viewGroup,int width,int height){
71 | //设置给ViewGroup容器
72 | // viewGroup.setLayoutTransition(new LayoutTransition());
73 | // ObjectAnimator addAnimator = ObjectAnimator.ofFloat(null, "translationX",height ,0);
74 | // ObjectAnimator removeAnimator = ObjectAnimator.ofFloat(null, "translationY", 0,- height);
75 | // viewGroup.getLayoutTransition().setDuration(100);
76 | // viewGroup.getLayoutTransition()
77 | // .setAnimator(LayoutTransition.APPEARING, addAnimator);
78 | // viewGroup.getLayoutTransition()
79 | // .setAnimator(LayoutTransition.DISAPPEARING, removeAnimator);
80 | //
81 |
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/lubottommenu/src/main/java/com/lu/lubottommenu/Utils.java:
--------------------------------------------------------------------------------
1 | package com.lu.lubottommenu;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.support.annotation.FloatRange;
6 | import android.util.DisplayMetrics;
7 | import android.view.WindowManager;
8 |
9 |
10 | /**
11 | * 工具类
12 | * Created by 陆正威 on 2017/4/6.
13 | */
14 |
15 | @SuppressWarnings({"WeakerAccess", "unused"})
16 | public class Utils {
17 |
18 | public static int[] getScreenSize(Context context) {
19 | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
20 | DisplayMetrics outMetrics = new DisplayMetrics();
21 | wm.getDefaultDisplay().getMetrics(outMetrics);
22 | return new int[]{outMetrics.widthPixels, outMetrics.heightPixels};
23 | }
24 |
25 | public static int dip2px(Context context,float dpValue) {
26 | final float scale = context.getResources().getDisplayMetrics().density;
27 | return (int) (dpValue * scale + 0.5f);
28 | }
29 |
30 | public static int px2dip(Context context,float pxValue) {
31 | final float scale = context.getResources().getDisplayMetrics().density;
32 | return (int) (pxValue / scale + 0.5f);
33 | }
34 |
35 |
36 | /**
37 | * @param color 处理的颜色
38 | * @param i 处理的步长
39 | * @return 处理完后较深的颜色
40 | */
41 | public static int getDarkerColor(int color , @FloatRange(from = 0,to = 1) float i){
42 | float redrate = 0.299f;
43 | float greenrate = 0.587f;
44 | float bluerate = 0.114f;
45 |
46 | int red = (color >> 16) & 0xFF;
47 | int green = (color >> 8) & 0xFF;
48 | int blue = color & 0xFF;
49 |
50 | return Color.rgb((int) Math.max(red - redrate * i * 0xFF,0),
51 | (int) Math.max(green - greenrate * i * 0xFF,0),
52 | (int) Math.max(blue - bluerate * i *0xFF , 0));
53 | }
54 |
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/lubottommenu/src/main/java/com/lu/lubottommenu/api/IBottomMenuItem.java:
--------------------------------------------------------------------------------
1 | package com.lu.lubottommenu.api;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 | import android.view.View;
6 |
7 | import com.lu.lubottommenu.logiclist.MenuItem;
8 |
9 | /**
10 | * Created by 陆正威 on 2017/9/6.
11 | */
12 |
13 | public interface IBottomMenuItem {
14 | Long getItemId();
15 | View getMainView();
16 |
17 | interface OnItemClickListenerParcelable extends Parcelable {
18 | void onItemClick(MenuItem item);
19 |
20 | @Override
21 | int describeContents();
22 |
23 | @Override
24 | void writeToParcel(Parcel dest, int flags);
25 | }
26 |
27 | interface OnBottomItemClickListener{
28 | boolean onItemClick(MenuItem item,boolean isSelected);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/lubottommenu/src/main/java/com/lu/lubottommenu/api/ITheme.java:
--------------------------------------------------------------------------------
1 | package com.lu.lubottommenu.api;
2 |
3 | import android.os.Parcelable;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * 自定义主题接口
9 | * Created by 陆正威 on 2017/9/17.
10 | */
11 |
12 | public interface ITheme extends Serializable,Parcelable{
13 | int[] getBackGroundColors();
14 | int getAccentColor();
15 | int getNormalColor();
16 | }
17 |
--------------------------------------------------------------------------------
/lubottommenu/src/main/java/com/lu/lubottommenu/logiclist/MenuItem.java:
--------------------------------------------------------------------------------
1 | package com.lu.lubottommenu.logiclist;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 | import android.view.View;
6 |
7 | import java.io.Serializable;
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | /**
12 | *
13 | * Created by 陆正威 on 2017/9/6.
14 | */
15 | public class MenuItem implements Serializable{
16 | private List