Showing preview only (243K chars total). Download the full file or copy to clipboard to get everything.
Repository: guanpy/WhiteBoard
Branch: master
Commit: 12e47c0c320b
Files: 91
Total size: 209.6 KB
Directory structure:
gitextract_yv6_nzdc/
├── .gitignore
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── example/
│ │ └── gpy/
│ │ └── whiteboard/
│ │ └── ApplicationTest.java
│ └── main/
│ ├── AndroidManifest.xml
│ ├── java/
│ │ └── com/
│ │ └── example/
│ │ └── gpy/
│ │ └── whiteboard/
│ │ ├── MainActivity.java
│ │ ├── SelfApplication.java
│ │ ├── bean/
│ │ │ └── WbInfo.java
│ │ ├── utils/
│ │ │ ├── FileUtil.java
│ │ │ ├── SdCardStatus.java
│ │ │ ├── StoreUtil.java
│ │ │ └── ToastUtils.java
│ │ └── view/
│ │ ├── WhiteBoardActivity.java
│ │ ├── base/
│ │ │ └── BaseActivity.java
│ │ └── widget/
│ │ └── floatingactionmenu/
│ │ ├── AddFloatingActionButton.java
│ │ ├── FloatingActionButton.java
│ │ ├── FloatingActionsMenu.java
│ │ ├── FloatingImageButton.java
│ │ └── TouchDelegateGroup.java
│ └── res/
│ ├── drawable/
│ │ ├── bg_white_board.xml
│ │ ├── common_cancel_selector.xml
│ │ ├── common_confirm_selector.xml
│ │ ├── draw_text_border.xml
│ │ ├── fab_label_background.xml
│ │ ├── ic_back_selector.xml
│ │ ├── white_board_add_selector.xml
│ │ ├── white_board_color_black_selector.xml
│ │ ├── white_board_color_green_selector.xml
│ │ ├── white_board_color_orange_selector.xml
│ │ ├── white_board_color_pink_selector.xml
│ │ ├── white_board_color_purple_selector.xml
│ │ ├── white_board_disable_selector.xml
│ │ ├── white_board_eraser_selected_selector.xml
│ │ ├── white_board_eraser_selector.xml
│ │ ├── white_board_export_selector.xml
│ │ ├── white_board_next_page_selector.xml
│ │ ├── white_board_pen_selected_selector.xml
│ │ ├── white_board_pen_selector.xml
│ │ ├── white_board_pre_page_selector.xml
│ │ ├── white_board_redo_selector.xml
│ │ ├── white_board_save_selector.xml
│ │ ├── white_board_text_bold_selected_selector.xml
│ │ ├── white_board_text_bold_selector.xml
│ │ ├── white_board_text_italics_selected_selector.xml
│ │ ├── white_board_text_italics_selector.xml
│ │ ├── white_board_text_selected_selector.xml
│ │ ├── white_board_text_selector.xml
│ │ ├── white_board_text_underline_selected_selector.xml
│ │ ├── white_board_text_underline_selector.xml
│ │ ├── white_board_undisable_selector.xml
│ │ └── white_board_undo_selector.xml
│ ├── layout/
│ │ ├── activity_main.xml
│ │ ├── activity_white_board.xml
│ │ ├── draw_text.xml
│ │ └── wb_item.xml
│ ├── values/
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── ids.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── values-w820dp/
│ └── dimens.xml
├── build.gradle
├── gradle.properties
├── settings.gradle
└── wblib/
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src/
├── androidTest/
│ └── java/
│ └── com/
│ └── github/
│ └── guanpy/
│ └── wblib/
│ └── ApplicationTest.java
└── main/
├── AndroidManifest.xml
├── java/
│ └── com/
│ └── github/
│ └── guanpy/
│ └── wblib/
│ ├── bean/
│ │ ├── DrawPenPoint.java
│ │ ├── DrawPenStr.java
│ │ ├── DrawPoint.java
│ │ ├── DrawTextPoint.java
│ │ ├── Point.java
│ │ ├── WhiteBoardPoint.java
│ │ └── WhiteBoardPoints.java
│ ├── utils/
│ │ ├── AppContextUtil.java
│ │ ├── BeanUtil.java
│ │ ├── Events.java
│ │ ├── OperationUtils.java
│ │ └── WhiteBoardVariable.java
│ └── widget/
│ ├── DrawPenView.java
│ ├── DrawTextLayout.java
│ └── DrawTextView.java
└── res/
├── drawable/
│ └── draw_text_border.xml
├── layout/
│ └── draw_text.xml
└── values/
├── colors.xml
└── strings.xml
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
#Android generated
bin
gen
lint.xml
lint
#Eclipse
.project
.classpath
.settings
.checkstyle
#IntelliJ IDEA
.idea
*.iml
*.ipr
*.iws
classes
gen-external-apklibs
#gradle
.gradle
local.properties
gradlew
gradlew.bat
gradle/
build/
#vi
*.swp
#other editors
*.bak
#Maven
target
release.properties
pom.xml.*
#Ant
build.xml
ant.properties
local.properties
proguard.cfg
proguard-project.txt
#Other
.DS_Store
Thumbs.db
tmp
*.tgz
*.lock
*.lck
com_crashlytics_export_strings.xml
================================================
FILE: README.md
================================================
# WhiteBoard
- 1、涂鸦功能:包括画笔粗细选择、颜色选择、橡皮擦等;
- 2、文字输入:包括颜色选择、增、删、改等;
- 3、白板功能:包括撤销、重做、新增、锁屏、切换、保存为图片、保存到本地等功能

## 预览


## TODO
- 1、DrawTextView的接口化
- 2、白板数据结构重定义
- 3、markId的重新加载问题
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.example.gpy.whiteboard"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':wblib')
compile 'com.android.support:appcompat-v7:23.1.1'
compile'com.squareup.retrofit:converter-jackson:1.9.0'
compile 'com.jakewharton:butterknife:6.1.0'
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\software\Java\Android\sdk_studio/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: app/src/androidTest/java/com/example/gpy/whiteboard/ApplicationTest.java
================================================
package com.example.gpy.whiteboard;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gpy.whiteboard">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:name=".SelfApplication"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".view.WhiteBoardActivity"
android:windowSoftInputMode="stateHidden|adjustResize"
android:screenOrientation="landscape">
</activity>
</application>
</manifest>
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/MainActivity.java
================================================
package com.example.gpy.whiteboard;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.example.gpy.whiteboard.utils.FileUtil;
import com.example.gpy.whiteboard.utils.StoreUtil;
import com.example.gpy.whiteboard.utils.ToastUtils;
import com.example.gpy.whiteboard.view.WhiteBoardActivity;
import com.example.gpy.whiteboard.view.base.BaseActivity;
import com.github.guanpy.wblib.utils.OperationUtils;
import java.io.File;
import java.util.ArrayList;
import butterknife.InjectView;
public class MainActivity extends BaseActivity {
@InjectView(R.id.lv_wb)
ListView mLv;
@InjectView(R.id.iv_wb_add)
ImageView mIvAdd;
private WbAdapter mWbAdapter;
ArrayList<String> filenames;
ArrayList<String> filepaths;
private long mBackPressedTime;
@Override
protected int getLayoutId() {
return R.layout.activity_main;
}
@Override
protected void afterCreate(Bundle savedInstanceState) {
loadData();
initView();
}
private void loadData() {
File folder = new File(StoreUtil.getWbPath());
if (!folder.exists()) {
folder.mkdirs();
}
final File[] files = folder.listFiles();
if (files.length > 0) {
filenames = new ArrayList<String>();
filepaths = new ArrayList<String>();
for (File f : files) {
filenames.add(FileUtil.getFileName(f));
filepaths.add(f.getAbsolutePath());
}
}
// mWbAdapter.notifyDataSetChanged();
}
private void initView() {
mWbAdapter = new WbAdapter();
mLv.setAdapter(mWbAdapter);
mIvAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OperationUtils.getInstance().initDrawPointList();
navi2Page(WhiteBoardActivity.class);
}
});
}
@Override
public void onBackPressed() {
final long mCurrentTime = System.currentTimeMillis();
if (mCurrentTime - this.mBackPressedTime > 1000) {
ToastUtils.showToast(this, R.string.app_logout);
this.mBackPressedTime = mCurrentTime;
return;
}
super.onBackPressed();
System.exit(0);
}
private class WbAdapter extends BaseAdapter {
@Override
public int getCount() {
return filenames != null ? filenames.size() : 0;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
WbViewHolder holder = null;
if (convertView != null) {
holder = (WbViewHolder) convertView.getTag();
} else {
convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.wb_item, null);
if (convertView != null) {
convertView.setTag(
holder = new WbViewHolder(convertView)
);
}
if (holder != null) {
holder.nWbName.setText(filenames.get(position));
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
StoreUtil.readWhiteBoardPoints(filepaths.get(position));
navi2Page(WhiteBoardActivity.class);
}
});
}
}
return convertView;
}
}
private final class WbViewHolder {
final TextView nWbName;
public WbViewHolder(final View view) {
this.nWbName = (TextView) view.findViewById(R.id.tv_wb_name);
}
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/SelfApplication.java
================================================
package com.example.gpy.whiteboard;
import android.app.Application;
import com.example.gpy.whiteboard.utils.SdCardStatus;
import com.example.gpy.whiteboard.utils.StoreUtil;
import com.github.guanpy.wblib.utils.AppContextUtil;
import com.github.guanpy.wblib.utils.OperationUtils;
/**
* Created by gpy on 2015/8/17.
*/
public class SelfApplication extends Application{
@Override
public void onCreate() {
super.onCreate();
AppContextUtil.init(this);
SdCardStatus.init(StoreUtil.CACHE_DIR);
OperationUtils.getInstance().init();
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/bean/WbInfo.java
================================================
package com.example.gpy.whiteboard.bean;
import java.io.File;
/**
* Created by gpy on 2016/4/22.
*/
public class WbInfo {
/**
* 文件名
*/
private String mName;
/**
* 文件
*/
private File mFile;
/**
* 获得文件名
* Created 2016-3-22 18:30:34
*
* @return 文件名
* @author gpy
*/
public String getName() {
return mName;
}
/**
* 设置文件名
* Created 2016-3-22 18:30:34
*
* @param name 文件名
* @author gpy
*/
public void setName(String name) {
this.mName = name;
}
/**
* 获得文件
* Created 2016-3-22 18:30:34
*
* @return 文件
* @author gpy
*/
public File getFile() {
return mFile;
}
/**
* 设置文件
* Created 2016-3-22 18:30:34
*
* @param file 文件
* @author gpy
*/
public void setFile(File file) {
this.mFile = file;
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/utils/FileUtil.java
================================================
package com.example.gpy.whiteboard.utils;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.text.DecimalFormat;
/**
* Created by gpy on 2016/4/6.
*/
public class FileUtil {
public static final int SIZETYPE_B = 1;// 获取文件大小单位为B的double值
public static final int SIZETYPE_KB = 2;// 获取文件大小单位为KB的double值
public static final int SIZETYPE_MB = 3;// 获取文件大小单位为MB的double值
public static final int SIZETYPE_GB = 4;// 获取文件大小单位为GB的double值
/**
* 获取指定文件名字
*
* @param file
* @return
*/
public static String getFileName(File file) {
final String name = file.getName();
if (!TextUtils.isEmpty(name)) {
final int ext = name.lastIndexOf(".");
if (ext > 0) {
return name.substring(0, ext);
}
}
return name;
}
/**
* 调用此方法自动计算指定文件或指定文件夹的大小
*
* @param filePath 文件路径
* @return 计算好的带B、KB、MB、GB的字符串
*/
public static String getAutoFileOrFilesSize(String filePath) {
File file = new File(filePath);
long blockSize = 0;
try {
if (file.isDirectory()) {
blockSize = getFileSizes(file);
} else {
blockSize = getFileSize(file);
}
} catch (Exception e) {
e.printStackTrace();
Log.e("获取文件大小", "获取失败!");
}
return FormetFileSize(blockSize);
}
/**
* 获取文件指定文件的指定单位的大小
*
* @param filePath 文件路径
* @param sizeType 获取大小的类型1为B、2为KB、3为MB、4为GB
* @return double值的大小
*/
public static double getFileOrFilesSize(String filePath, int sizeType) {
File file = new File(filePath);
long blockSize = 0;
try {
if (file.isDirectory()) {
blockSize = getFileSizes(file);
} else {
blockSize = getFileSize(file);
}
} catch (Exception e) {
e.printStackTrace();
Log.e("获取文件大小", "获取失败!");
}
return FormetFileSize(blockSize, sizeType);
}
/**
* 获取指定文件大小
*
* @param file
* @return
* @throws Exception
*/
private static long getFileSize(File file) throws Exception {
long size = 0;
if (file.exists()) {
FileInputStream fis = null;
fis = new FileInputStream(file);
size = fis.available();
} else {
file.createNewFile();
Log.e("获取文件大小", "文件不存在!");
}
return size;
}
/**
* 获取指定文件夹
*
* @param f
* @return
* @throws Exception
*/
private static long getFileSizes(File f) throws Exception {
long size = 0;
File flist[] = f.listFiles();
for (int i = 0; i < flist.length; i++) {
if (flist[i].isDirectory()) {
size = size + getFileSizes(flist[i]);
} else {
size = size + getFileSize(flist[i]);
}
}
return size;
}
/**
* 转换文件大小
*
* @param fileS
* @return
*/
private static String FormetFileSize(long fileS) {
DecimalFormat df = new DecimalFormat("#.00");
String fileSizeString = "";
String wrongSize = "0B";
if (fileS == 0) {
return wrongSize;
}
if (fileS < 1024) {
fileSizeString = df.format((double) fileS) + "B";
} else if (fileS < 1048576) {
fileSizeString = df.format((double) fileS / 1024) + "KB";
} else if (fileS < 1073741824) {
fileSizeString = df.format((double) fileS / 1048576) + "MB";
} else {
fileSizeString = df.format((double) fileS / 1073741824) + "GB";
}
return fileSizeString;
}
/**
* 转换文件大小,指定转换的类型
*
* @param fileS
* @param sizeType
* @return
*/
private static double FormetFileSize(long fileS, int sizeType) {
DecimalFormat df = new DecimalFormat("#.00");
double fileSizeLong = 0;
switch (sizeType) {
case SIZETYPE_B:
fileSizeLong = Double.valueOf(df.format((double) fileS));
break;
case SIZETYPE_KB:
fileSizeLong = Double.valueOf(df.format((double) fileS / 1024));
break;
case SIZETYPE_MB:
fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576));
break;
case SIZETYPE_GB:
fileSizeLong = Double.valueOf(df
.format((double) fileS / 1073741824));
break;
default:
break;
}
return fileSizeLong;
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/utils/SdCardStatus.java
================================================
package com.example.gpy.whiteboard.utils;
import android.os.Environment;
import java.io.File;
/**
* Created by gpy on 2015/10/20.
*/
public class SdCardStatus {
private static String CACHE_FOLDER_NAME;
private static String NONE_SD_CARD_PROMPT = "您的手机中sd卡不存在";
public static void init(String cacheFolderName) {
CACHE_FOLDER_NAME = cacheFolderName;
}
public static String getDefaulstCacheDirInSdCard() throws IllegalStateException {
String sdCardPath = null;
sdCardPath = getSDPath();
if (null == sdCardPath) {
throw new IllegalStateException(NONE_SD_CARD_PROMPT);
}
return sdCardPath + File.separator + CACHE_FOLDER_NAME;
}
/**
* when not exist sd card,return null.
*
* @return
*/
public static String getSDPath() {
boolean sdCardExist = Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
if (sdCardExist) {
return Environment.getExternalStorageDirectory().getAbsolutePath();
} else {
return null;
}
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/utils/StoreUtil.java
================================================
package com.example.gpy.whiteboard.utils;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.text.TextUtils;
import android.util.Log;
import com.example.gpy.whiteboard.R;
import com.github.guanpy.wblib.bean.DrawPenPoint;
import com.github.guanpy.wblib.bean.DrawPenStr;
import com.github.guanpy.wblib.bean.DrawPoint;
import com.github.guanpy.wblib.bean.Point;
import com.github.guanpy.wblib.bean.WhiteBoardPoint;
import com.github.guanpy.wblib.bean.WhiteBoardPoints;
import com.github.guanpy.wblib.utils.AppContextUtil;
import com.github.guanpy.wblib.utils.OperationUtils;
import com.google.gson.Gson;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
/**
* 存储空间工具类
* Created by gpy on 2015/8/2.
*/
public class StoreUtil {
private static final String TAG = "StoreUtil";
private static final String CHARSET = "UTF-8";
public static final String CACHE_DIR = "WhiteBoard";
private static final String CACHE_DIR_PHOTO = "photo";
private static final String PHOTO_FORMAT_PNG = ".png";
private static final String CACHE_DIR_WB = "wb";
private static final String WB_FORMAT = ".wb";
/**
* 获取保存路径
*/
public static String getPhotoSavePath() {
return getPhotoPath() + File.separator + UUID.randomUUID().toString() + PHOTO_FORMAT_PNG;
}
public static String getPhotoPath() {
return SdCardStatus.getDefaulstCacheDirInSdCard() + File.separator + CACHE_DIR_PHOTO;
}
/**
* 获取保存路径
*/
public static String getWbSavePath() {
return getWbPath() + File.separator + UUID.randomUUID().toString() + WB_FORMAT;
}
public static String getWbPath() {
return SdCardStatus.getDefaulstCacheDirInSdCard() + File.separator + CACHE_DIR_WB;
}
/**
* 存储白板集
*/
public static void saveWhiteBoardPoints() {
WhiteBoardPoints whiteBoardPoints = OperationUtils.getInstance().getWhiteBoardPoints();
if (whiteBoardPoints == null || whiteBoardPoints.getWhiteBoardPoints() == null || whiteBoardPoints.getWhiteBoardPoints().isEmpty()) {
return;
}
for (WhiteBoardPoint whiteBoardPoint : whiteBoardPoints.getWhiteBoardPoints()) {//清除绘画路径,保留字符串形式就行
for (DrawPoint drawPoint : whiteBoardPoint.getSavePoints()) {
if (drawPoint.getType() == OperationUtils.DRAW_PEN) {
drawPoint.setDrawPen(null);
}
}
}
String strJson = new Gson().toJson(whiteBoardPoints);
StoreUtil.write(strJson, getWbSavePath());
convertWhiteBoardPoints(whiteBoardPoints);
OperationUtils.getInstance().setWhiteBoardPoints(whiteBoardPoints);
ToastUtils.showToast(AppContextUtil.getContext(), AppContextUtil.getContext().getString(R.string.white_board_save_sucess));
}
/**
* 读取白板集
*/
public static void readWhiteBoardPoints(String filePath) {
String strJson = StoreUtil.read(filePath);
if (!TextUtils.isEmpty(strJson)) {
WhiteBoardPoints whiteBoardPoints = new Gson().fromJson(strJson, WhiteBoardPoints.class);
convertWhiteBoardPoints(whiteBoardPoints);
OperationUtils.getInstance().setWhiteBoardPoints(whiteBoardPoints);
}
}
/**
* 从json字符中将Path、Paint系统类转换出来
*/
public static void convertWhiteBoardPoints(WhiteBoardPoints whiteBoardPoints) {
for (WhiteBoardPoint whiteBoardPoint : whiteBoardPoints.getWhiteBoardPoints()) {
whiteBoardPoint.getDeletePoints().clear();
for (DrawPoint drawPoint : whiteBoardPoint.getSavePoints()) {
if (drawPoint.getType() == OperationUtils.DRAW_PEN) {
DrawPenStr drawPenStr = drawPoint.getDrawPenStr();
Paint paint = new Paint();
paint.setAntiAlias(true);//是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢
paint.setDither(true);// 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
paint.setColor(drawPenStr.getColor());//设置绘制的颜色
paint.setStyle(Paint.Style.STROKE);//设置画笔的样式
paint.setStrokeJoin(Paint.Join.ROUND);//设置绘制时各图形的结合方式,如平滑效果等
paint.setStrokeCap(Paint.Cap.ROUND);//当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,如圆形样式 Cap.ROUND,或方形样式Cap.SQUARE
paint.setStrokeWidth(drawPenStr.getStrokeWidth());//当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度
if (drawPenStr.getIsEraser()) {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));//擦除模式
}
Path path = new Path();
path.moveTo(drawPenStr.getMoveTo().getX(), drawPenStr.getMoveTo().getY());
for (int i = 0; i < drawPenStr.getQuadToA().size(); i++) {
Point pointA = drawPenStr.getQuadToA().get(i);
Point pointB = drawPenStr.getQuadToB().get(i);
path.quadTo(pointA.getX(), pointA.getY(), pointB.getX(), pointB.getY());
}
path.lineTo(drawPenStr.getLineTo().getX(), drawPenStr.getLineTo().getY());
path.offset(drawPenStr.getOffset().getX(), drawPenStr.getOffset().getY());
DrawPenPoint drawPenPoint = new DrawPenPoint();
drawPenPoint.setPaint(paint);
drawPenPoint.setPath(path);
drawPoint.setDrawPen(drawPenPoint);
}
}
}
}
/**
* 保存内容到文件中
*/
public static void write(String strWb, String path) {
if (TextUtils.isEmpty(strWb) || TextUtils.isEmpty(path)) {
Log.d(TAG, "Trying to save null or 0 length strWb or path");
return;
}
File toFile = new File(path);
if (!toFile.getParentFile().exists()) {
toFile.getParentFile().mkdirs();
}
if (toFile.exists()) {
toFile.delete();
}
try {
toFile.createNewFile();
} catch (IOException e) {
Log.e(TAG, "IOException:" + e.getMessage());
toFile = null;
} finally {
if (null != toFile && null != strWb) {
OutputStream outStream = null;
try {
outStream = new FileOutputStream(toFile);
} catch (FileNotFoundException e) {
Log.d(TAG, "FileNotFoundException:" + e.getMessage());
outStream = null;
} finally {
if (null != outStream) {
try {
outStream.write(strWb.getBytes("utf-8"));
outStream.flush();
} catch (IOException e) {
Log.e(TAG, "IOException:" + e.getMessage());
} finally {
try {
if (null != outStream) {
outStream.close();
}
} catch (IOException e) {
Log.d(TAG, "IOException" + e.getMessage());
}
}
}
}
}
}
}
/**
* 加载文件内容
*/
public static String read(String wbPath) {
File file = new File(wbPath);
if (file.exists()) {
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
int len = fis.available();
if (len > 0) {
byte[] buf = new byte[len];
fis.read(buf);
String string = new String(buf, CHARSET);
return string;
}
} catch (Exception e) {
e.printStackTrace();
} catch (OutOfMemoryError e) {
e.printStackTrace();
} finally {
if (fis != null)
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/utils/ToastUtils.java
================================================
package com.example.gpy.whiteboard.utils;
import android.content.Context;
import android.widget.Toast;
/**
* Created by gpy on 2016/4/11.
*/
public class ToastUtils {
public static void showToast(Context context, String string) {
Toast.makeText(context, string, Toast.LENGTH_SHORT).show();
}
public static void showToast(Context context, int intStr) {
Toast.makeText(context, intStr, Toast.LENGTH_SHORT).show();
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/view/WhiteBoardActivity.java
================================================
package com.example.gpy.whiteboard.view;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.example.gpy.whiteboard.R;
import com.example.gpy.whiteboard.utils.StoreUtil;
import com.example.gpy.whiteboard.view.base.BaseActivity;
import com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingActionsMenu;
import com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton;
import com.github.guanpy.library.ann.ReceiveEvents;
import com.github.guanpy.wblib.bean.DrawPoint;
import com.github.guanpy.wblib.utils.Events;
import com.github.guanpy.wblib.utils.OperationUtils;
import com.github.guanpy.wblib.utils.WhiteBoardVariable;
import com.github.guanpy.wblib.widget.DrawPenView;
import com.github.guanpy.wblib.widget.DrawTextLayout;
import com.github.guanpy.wblib.widget.DrawTextView;
import java.io.File;
import java.io.FileOutputStream;
import butterknife.InjectView;
/**
* 白板工具
* Created by gpy on 2015/6/2.
*/
public class WhiteBoardActivity extends BaseActivity implements View.OnClickListener {
@InjectView(R.id.iv_white_board_book)
ImageView mIvWhiteBoardBook;
@InjectView(R.id.rl_head)
RelativeLayout mRlHead;
@InjectView(R.id.iv_white_board_back)
ImageView mIvWhiteBoardBack;
@InjectView(R.id.tv_white_board_head)
TextView mTvWhiteBoardHead;
@InjectView(R.id.iv_white_board_export)
ImageView mIvWhiteBoardExport;
@InjectView(R.id.iv_white_board_save)
ImageView mIvWhiteBoardSave;
@InjectView(R.id.fl_view)
FrameLayout mFlView;
@InjectView(R.id.db_view)
DrawPenView mDbView;
@InjectView(R.id.dt_view)
DrawTextLayout mDtView;
@InjectView(R.id.fab_menu_size)
FloatingActionsMenu mFabMenuSize;
@InjectView(R.id.bt_size_large)
FloatingImageButton mBtSizeLarge;
@InjectView(R.id.bt_size_middle)
FloatingImageButton mBtSizeMiddle;
@InjectView(R.id.bt_size_mini)
FloatingImageButton mBtSizeMini;
@InjectView(R.id.fab_menu_color)
FloatingActionsMenu mFabMenuColor;
@InjectView(R.id.bt_color_green)
FloatingImageButton mBtColorGreen;
@InjectView(R.id.bt_color_purple)
FloatingImageButton mBtColorPurple;
@InjectView(R.id.bt_color_pink)
FloatingImageButton mBtColorPink;
@InjectView(R.id.bt_color_orange)
FloatingImageButton mBtColorOrange;
@InjectView(R.id.bt_color_black)
FloatingImageButton mBtColorBlack;
@InjectView(R.id.fab_menu_text)
FloatingActionsMenu mFabMenuText;
@InjectView(R.id.bt_text_underline)
FloatingImageButton mBtTextUnderline;
@InjectView(R.id.bt_text_italics)
FloatingImageButton mBtTextItalics;
@InjectView(R.id.bt_text_bold)
FloatingImageButton mBtTextBold;
@InjectView(R.id.fab_menu_eraser)
FloatingActionsMenu mFabMenuEraser;
@InjectView(R.id.bt_eraser_large)
FloatingImageButton mBtEraserLarge;
@InjectView(R.id.bt_eraser_middle)
FloatingImageButton mBtEraserMiddle;
@InjectView(R.id.bt_eraser_mini)
FloatingImageButton mBtEraserMini;
@InjectView(R.id.iv_white_board_undo)
ImageView mIvWhiteBoardUndo;
@InjectView(R.id.iv_white_board_redo)
ImageView mIvWhiteBoardRedo;
@InjectView(R.id.ll_white_board_page)
LinearLayout mLlWhiteBoardPage;
@InjectView(R.id.iv_white_board_pre)
ImageView mIvWhiteBoardPre;
@InjectView(R.id.tv_white_board_page)
TextView mTvWhiteBoardPage;
@InjectView(R.id.iv_white_board_next)
ImageView mIvWhiteBoardNext;
@InjectView(R.id.iv_white_board_add)
ImageView mIvWhiteBoardAdd;
@InjectView(R.id.iv_white_board_disable)
ImageView mIvWhiteBoardDisable;
@InjectView(R.id.iv_white_board_quit)
ImageView mIvWhiteBoardQuit;
@InjectView(R.id.iv_white_board_confirm)
ImageView mIvWhiteBoardConfirm;
@InjectView(R.id.rl_content)
RelativeLayout mRlContent;
@InjectView(R.id.rl_bottom)
RelativeLayout mRlBottom;
@InjectView(R.id.v_bottom_back)
View mVBottomBack;
@InjectView(R.id.ll_white_board_pre)
LinearLayout mLlWhiteBoardPre;
@InjectView(R.id.ll_white_board_next)
LinearLayout mLlWhiteBoardNext;
@Override
protected void afterCreate(Bundle bundle) {
initView();
initEvent();
}
private void initView() {
changePenBack();
changeColorBack();
changeEraserBack();
ToolsOperation(WhiteBoardVariable.Operation.PEN_NORMAL);
mDbView.post(new Runnable() {
@Override
public void run() {
showPoints();
}
});
}
private void initEvent() {
//头部
mIvWhiteBoardBack.setOnClickListener(this);
mIvWhiteBoardExport.setOnClickListener(this);
mIvWhiteBoardSave.setOnClickListener(this);
mIvWhiteBoardQuit.setOnClickListener(this);
mIvWhiteBoardConfirm.setOnClickListener(this);
mVBottomBack.setOnClickListener(this);
//画笔尺寸大小
mFabMenuSize.setOnFloatingActionsMenuClickListener(new FloatingActionsMenu.OnFloatingActionsMenuClickListener() {
@Override
public void addButtonLister() {
ToolsOperation(WhiteBoardVariable.Operation.PEN_CLICK);
}
});
mBtSizeLarge.setOnClickListener(this);
mBtSizeMiddle.setOnClickListener(this);
mBtSizeMini.setOnClickListener(this);
//画笔或者文字颜色
mFabMenuColor.setOnFloatingActionsMenuClickListener(new FloatingActionsMenu.OnFloatingActionsMenuClickListener() {
@Override
public void addButtonLister() {
ToolsOperation(WhiteBoardVariable.Operation.COLOR_CLICK);
}
});
mBtColorGreen.setOnClickListener(this);
mBtColorPurple.setOnClickListener(this);
mBtColorPink.setOnClickListener(this);
mBtColorOrange.setOnClickListener(this);
mBtColorBlack.setOnClickListener(this);
//文字样式
mFabMenuText.setOnFloatingActionsMenuClickListener(new FloatingActionsMenu.OnFloatingActionsMenuClickListener() {
@Override
public void addButtonLister() {
ToolsOperation(WhiteBoardVariable.Operation.TEXT_CLICK);
}
});
mBtTextUnderline.setOnClickListener(this);
mBtTextItalics.setOnClickListener(this);
mBtTextBold.setOnClickListener(this);
//橡皮擦尺寸大小
mFabMenuEraser.setOnFloatingActionsMenuClickListener(new FloatingActionsMenu.OnFloatingActionsMenuClickListener() {
@Override
public void addButtonLister() {
ToolsOperation(WhiteBoardVariable.Operation.ERASER_CLICK);
}
});
mBtEraserLarge.setOnClickListener(this);
mBtEraserMiddle.setOnClickListener(this);
mBtEraserMini.setOnClickListener(this);
mIvWhiteBoardUndo.setOnClickListener(this);
mIvWhiteBoardRedo.setOnClickListener(this);
mLlWhiteBoardPre.setOnClickListener(this);
mIvWhiteBoardPre.setOnClickListener(this);
mLlWhiteBoardNext.setOnClickListener(this);
mIvWhiteBoardNext.setOnClickListener(this);
mIvWhiteBoardAdd.setOnClickListener(this);
mIvWhiteBoardDisable.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.iv_white_board_back://返回键
onBackPressed();
break;
case R.id.iv_white_board_quit://退出文字编辑
afterEdit(false);
break;
case R.id.iv_white_board_confirm://保存文字编辑
afterEdit(true);
break;
case R.id.iv_white_board_export://保存白板操作集到本地
ToolsOperation(WhiteBoardVariable.Operation.OUTSIDE_CLICK);
StoreUtil.saveWhiteBoardPoints();
break;
case R.id.iv_white_board_save://保存白板为图片
ToolsOperation(WhiteBoardVariable.Operation.OUTSIDE_CLICK);
saveImage();
break;
case R.id.v_bottom_back://点击挡板
ToolsOperation(WhiteBoardVariable.Operation.OUTSIDE_CLICK);
break;
case R.id.bt_size_large://设置画笔尺寸-大号
setPenSize(WhiteBoardVariable.PenSize.LARRGE);
break;
case R.id.bt_size_middle://设置画笔尺寸-中号
setPenSize(WhiteBoardVariable.PenSize.MIDDLE);
break;
case R.id.bt_size_mini://设置画笔尺寸-小号
setPenSize(WhiteBoardVariable.PenSize.MINI);
break;
case R.id.bt_color_green://设置颜色-绿色
setColor(WhiteBoardVariable.Color.GREEN);
break;
case R.id.bt_color_purple://设置颜色-紫色
setColor(WhiteBoardVariable.Color.PURPLE);
break;
case R.id.bt_color_pink://设置颜色-粉色
setColor(WhiteBoardVariable.Color.PINK);
break;
case R.id.bt_color_orange://设置颜色-橙色
setColor(WhiteBoardVariable.Color.ORANGE);
break;
case R.id.bt_color_black://设置颜色-黑色
setColor(WhiteBoardVariable.Color.BLACK);
break;
case R.id.bt_text_underline://设置文字样式-下划线
setTextStyle(WhiteBoardVariable.TextStyle.CHANGE_UNDERLINE);
break;
case R.id.bt_text_italics://设置文字样式-斜体
setTextStyle(WhiteBoardVariable.TextStyle.CHANGE_ITALICS);
break;
case R.id.bt_text_bold://设置文字样式-粗体
setTextStyle(WhiteBoardVariable.TextStyle.CHANGE_BOLD);
break;
case R.id.bt_eraser_large://设置橡皮擦尺寸-大号
setEraserSize(WhiteBoardVariable.EraserSize.LARRGE);
break;
case R.id.bt_eraser_middle://设置橡皮擦尺寸-中号
setEraserSize(WhiteBoardVariable.EraserSize.MIDDLE);
break;
case R.id.bt_eraser_mini://设置橡皮擦尺寸-小号
setEraserSize(WhiteBoardVariable.EraserSize.MINI);
break;
case R.id.iv_white_board_undo://撤销
ToolsOperation(WhiteBoardVariable.Operation.OUTSIDE_CLICK);
if (OperationUtils.getInstance().DISABLE) {
undo();
}
break;
case R.id.iv_white_board_redo://重做
ToolsOperation(WhiteBoardVariable.Operation.OUTSIDE_CLICK);
if (OperationUtils.getInstance().DISABLE) {
redo();
}
break;
case R.id.ll_white_board_pre:
case R.id.iv_white_board_pre://上一页
ToolsOperation(WhiteBoardVariable.Operation.OUTSIDE_CLICK);
prePage();
break;
case R.id.ll_white_board_next:
case R.id.iv_white_board_next://下一页
ToolsOperation(WhiteBoardVariable.Operation.OUTSIDE_CLICK);
nextPage();
break;
case R.id.iv_white_board_add://新建白板
ToolsOperation(WhiteBoardVariable.Operation.OUTSIDE_CLICK);
newPage();
break;
case R.id.iv_white_board_disable://禁止/解禁按钮
ToolsOperation(WhiteBoardVariable.Operation.OUTSIDE_CLICK);
if (OperationUtils.getInstance().DISABLE) {
OperationUtils.getInstance().DISABLE = false;
mIvWhiteBoardDisable.setImageResource(R.drawable.white_board_undisable_selector);
mRlBottom.setVisibility(View.GONE);
} else {
OperationUtils.getInstance().DISABLE = true;
mIvWhiteBoardDisable.setImageResource(R.drawable.white_board_disable_selector);
mRlBottom.setVisibility(View.VISIBLE);
}
break;
}
}
/**
* 设置画笔尺寸
*/
private void setPenSize(int size) {
OperationUtils.getInstance().mCurrentPenSize = size;
changePenBack();
mDbView.setPenSize();
}
/**
* 切换画笔尺寸按按钮背景
*/
private void changePenBack() {
if (OperationUtils.getInstance().mCurrentPenSize == WhiteBoardVariable.PenSize.LARRGE) {
mBtSizeLarge.drawCircleAndRing(WhiteBoardVariable.PenSize.LARRGE, OperationUtils.getInstance().mCurrentColor);
mBtSizeMiddle.drawCircle(WhiteBoardVariable.PenSize.MIDDLE);
mBtSizeMini.drawCircle(WhiteBoardVariable.PenSize.MINI);
} else if (OperationUtils.getInstance().mCurrentPenSize == WhiteBoardVariable.PenSize.MIDDLE) {
mBtSizeLarge.drawCircle(WhiteBoardVariable.PenSize.LARRGE);
mBtSizeMiddle.drawCircleAndRing(WhiteBoardVariable.PenSize.MIDDLE, OperationUtils.getInstance().mCurrentColor);
mBtSizeMini.drawCircle(WhiteBoardVariable.PenSize.MINI);
} else if (OperationUtils.getInstance().mCurrentPenSize == WhiteBoardVariable.PenSize.MINI) {
mBtSizeLarge.drawCircle(WhiteBoardVariable.PenSize.LARRGE);
mBtSizeMiddle.drawCircle(WhiteBoardVariable.PenSize.MIDDLE);
mBtSizeMini.drawCircleAndRing(WhiteBoardVariable.PenSize.MINI, OperationUtils.getInstance().mCurrentColor);
}
}
/**
* 设置颜色
*/
private void setColor(int color) {
OperationUtils.getInstance().mCurrentColor = color;
changeColorBack();
setPenSize(OperationUtils.getInstance().mCurrentPenSize);
mDbView.setPenColor();
mDtView.setTextColor();
}
/**
* 切换颜色控制按钮背景
*/
private void changeColorBack() {
if (OperationUtils.getInstance().mCurrentColor == WhiteBoardVariable.Color.BLACK) {
mFabMenuColor.setAddButtonBackground(R.drawable.white_board_color_black_selector);
} else if (OperationUtils.getInstance().mCurrentColor == WhiteBoardVariable.Color.ORANGE) {
mFabMenuColor.setAddButtonBackground(R.drawable.white_board_color_orange_selector);
} else if (OperationUtils.getInstance().mCurrentColor == WhiteBoardVariable.Color.PINK) {
mFabMenuColor.setAddButtonBackground(R.drawable.white_board_color_pink_selector);
} else if (OperationUtils.getInstance().mCurrentColor == WhiteBoardVariable.Color.PURPLE) {
mFabMenuColor.setAddButtonBackground(R.drawable.white_board_color_purple_selector);
} else if (OperationUtils.getInstance().mCurrentColor == WhiteBoardVariable.Color.GREEN) {
mFabMenuColor.setAddButtonBackground(R.drawable.white_board_color_green_selector);
}
}
/**
* 设置文字风格
*/
private void setTextStyle(int textStyle) {
mDtView.setTextStyle(textStyle);
changeTextBack();
}
/**
* 切换文字相关按钮背景
*/
private void changeTextBack() {
int size = OperationUtils.getInstance().getSavePoints().size();
if (size < 1) {
return;
}
DrawPoint dp = OperationUtils.getInstance().getSavePoints().get(size - 1);
if (dp.getType() != OperationUtils.DRAW_TEXT) {
return;
}
if (dp.getDrawText().getIsUnderline()) {
mBtTextUnderline.setBackgroundResource(R.drawable.white_board_text_underline_selected_selector);
} else {
mBtTextUnderline.setBackgroundResource(R.drawable.white_board_text_underline_selector);
}
if (dp.getDrawText().getIsItalics()) {
mBtTextItalics.setBackgroundResource(R.drawable.white_board_text_italics_selected_selector);
} else {
mBtTextItalics.setBackgroundResource(R.drawable.white_board_text_italics_selector);
}
if (dp.getDrawText().getIsBold()) {
mBtTextBold.setBackgroundResource(R.drawable.white_board_text_bold_selected_selector);
} else {
mBtTextBold.setBackgroundResource(R.drawable.white_board_text_bold_selector);
}
}
/**
* 设置橡皮擦尺寸
*/
private void setEraserSize(int size) {
OperationUtils.getInstance().mCurrentEraserSize = size;
changeEraserBack();
mDbView.setEraserSize();
}
/**
* 切换橡皮擦尺寸按钮背景
*/
private void changeEraserBack() {
if (OperationUtils.getInstance().mCurrentEraserSize == WhiteBoardVariable.EraserSize.LARRGE) {
mBtEraserLarge.drawCircleAndRing(WhiteBoardVariable.EraserSize.LARRGE, WhiteBoardVariable.Color.BLACK);
mBtEraserMiddle.drawCircle(WhiteBoardVariable.EraserSize.MIDDLE, WhiteBoardVariable.Color.BLACK);
mBtEraserMini.drawCircle(WhiteBoardVariable.EraserSize.MINI, WhiteBoardVariable.Color.BLACK);
} else if (OperationUtils.getInstance().mCurrentEraserSize == WhiteBoardVariable.EraserSize.MIDDLE) {
mBtEraserLarge.drawCircle(WhiteBoardVariable.EraserSize.LARRGE, WhiteBoardVariable.Color.BLACK);
mBtEraserMiddle.drawCircleAndRing(WhiteBoardVariable.EraserSize.MIDDLE, WhiteBoardVariable.Color.BLACK);
mBtEraserMini.drawCircle(WhiteBoardVariable.EraserSize.MINI, WhiteBoardVariable.Color.BLACK);
} else if (OperationUtils.getInstance().mCurrentEraserSize == WhiteBoardVariable.EraserSize.MINI) {
mBtEraserLarge.drawCircle(WhiteBoardVariable.EraserSize.LARRGE, WhiteBoardVariable.Color.BLACK);
mBtEraserMiddle.drawCircle(WhiteBoardVariable.EraserSize.MIDDLE, WhiteBoardVariable.Color.BLACK);
mBtEraserMini.drawCircleAndRing(WhiteBoardVariable.EraserSize.MINI, WhiteBoardVariable.Color.BLACK);
}
}
/**
* 新建白板
*/
private void newPage() {
OperationUtils.getInstance().newPage();
showPoints();
}
/**
* 上一页
*/
private void prePage() {
if (OperationUtils.getInstance().mCurrentIndex > 0) {
OperationUtils.getInstance().mCurrentIndex--;
showPoints();
}
}
/**
* 下一页
*/
private void nextPage() {
if (OperationUtils.getInstance().mCurrentIndex + 1 < OperationUtils.getInstance().getDrawPointSize()) {
OperationUtils.getInstance().mCurrentIndex++;
showPoints();
}
}
/**
* 重新显示白板
*/
private void showPoints() {
mDbView.showPoints();
mDtView.showPoints();
mTvWhiteBoardPage.setText("" + (OperationUtils.getInstance().mCurrentIndex + 1) + "/" + OperationUtils.getInstance().getDrawPointSize());
showPage();
showUndoRedo();
}
/**
* 显示上下页是否可点击
*/
private void showPage() {
if (OperationUtils.getInstance().mCurrentIndex + 1 == OperationUtils.getInstance().getDrawPointSize()) {
mIvWhiteBoardNext.setImageResource(R.drawable.white_board_next_page_click);
} else {
mIvWhiteBoardNext.setImageResource(R.drawable.white_board_next_page_selector);
}
if (OperationUtils.getInstance().mCurrentIndex == 0) {
mIvWhiteBoardPre.setImageResource(R.drawable.white_board_pre_page_click);
} else {
mIvWhiteBoardPre.setImageResource(R.drawable.white_board_pre_page_selector);
}
}
/**
* 撤销
*/
private void undo() {
int size = OperationUtils.getInstance().getSavePoints().size();
if (size == 0) {
return;
} else {
OperationUtils.getInstance().getDeletePoints().add(OperationUtils.getInstance().getSavePoints().get(size - 1));
OperationUtils.getInstance().getSavePoints().remove(size - 1);
size = OperationUtils.getInstance().getDeletePoints().size();
if (OperationUtils.getInstance().getDeletePoints().get(size - 1).getType() == OperationUtils.DRAW_PEN) {
mDbView.undo();
} else if (OperationUtils.getInstance().getDeletePoints().get(size - 1).getType() == OperationUtils.DRAW_TEXT) {
mDtView.undo();
}
showUndoRedo();
}
}
/**
* 重做
*/
private void redo() {
int size = OperationUtils.getInstance().getDeletePoints().size();
if (size == 0) {
return;
} else {
OperationUtils.getInstance().getSavePoints().add(OperationUtils.getInstance().getDeletePoints().get(size - 1));
OperationUtils.getInstance().getDeletePoints().remove(size - 1);
size = OperationUtils.getInstance().getSavePoints().size();
if (OperationUtils.getInstance().getSavePoints().get(size - 1).getType() == OperationUtils.DRAW_PEN) {
mDbView.redo();
} else if (OperationUtils.getInstance().getSavePoints().get(size - 1).getType() == OperationUtils.DRAW_TEXT) {
mDtView.redo();
}
showUndoRedo();
}
}
@Override
protected int getLayoutId() {
return R.layout.activity_white_board;
}
/**
* 文字编辑之后
*/
private void afterEdit(boolean isSave) {
mIvWhiteBoardBack.setVisibility(View.VISIBLE);
mIvWhiteBoardExport.setVisibility(View.VISIBLE);
mIvWhiteBoardSave.setVisibility(View.VISIBLE);
mRlBottom.setVisibility(View.VISIBLE);
mIvWhiteBoardDisable.setVisibility(View.VISIBLE);
// mLayoutParams = (RelativeLayout.LayoutParams) mRlContent.getLayoutParams();
// mLayoutParams.setMargins(OperationUtils.dip2px(24), 0, OperationUtils.dip2px(24), OperationUtils.dip2px(24));
// mRlContent.setLayoutParams(mLayoutParams);
mIvWhiteBoardQuit.setVisibility(View.GONE);
mIvWhiteBoardConfirm.setVisibility(View.GONE);
mDbView.showPoints();
mDtView.afterEdit(isSave);
}
/**
* 白板工具栏点击切换操作
*/
private void ToolsOperation(int currentOperation) {
setPenOperation(currentOperation);
setColorOperation(currentOperation);
setTextOperation(currentOperation);
setEraserOperation(currentOperation);
showOutSideView();
}
/**
* 显示挡板
*/
private void showOutSideView() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (OperationUtils.getInstance().mCurrentOPerationPen == WhiteBoardVariable.Operation.PEN_EXPAND
|| OperationUtils.getInstance().mCurrentOPerationColor == WhiteBoardVariable.Operation.COLOR_EXPAND
|| OperationUtils.getInstance().mCurrentOPerationText == WhiteBoardVariable.Operation.TEXT_EXPAND
|| OperationUtils.getInstance().mCurrentOPerationEraser == WhiteBoardVariable.Operation.ERASER_EXPAND) {
mVBottomBack.setVisibility(View.VISIBLE);
} else {
mVBottomBack.setVisibility(View.GONE);
}
}
}, 100);
}
/**
* 白板工具栏点击切换操作-画笔
*/
private void setPenOperation(int currentOperation) {
switch (currentOperation) {
case WhiteBoardVariable.Operation.PEN_CLICK:
switch (OperationUtils.getInstance().mCurrentOPerationPen) {
case WhiteBoardVariable.Operation.PEN_NORMAL:
OperationUtils.getInstance().mCurrentDrawType = OperationUtils.DRAW_PEN;
mDbView.setPaint(null);
mFabMenuSize.setAddButtonBackground(R.drawable.white_board_pen_selected_selector);
OperationUtils.getInstance().mCurrentOPerationPen = WhiteBoardVariable.Operation.PEN_CLICK;
break;
case WhiteBoardVariable.Operation.PEN_CLICK:
mFabMenuSize.expand();
changePenBack();
OperationUtils.getInstance().mCurrentOPerationPen = WhiteBoardVariable.Operation.PEN_EXPAND;
break;
case WhiteBoardVariable.Operation.PEN_EXPAND:
mFabMenuSize.collapse();
OperationUtils.getInstance().mCurrentOPerationPen = WhiteBoardVariable.Operation.PEN_CLICK;
break;
}
break;
case WhiteBoardVariable.Operation.TEXT_CLICK:
case WhiteBoardVariable.Operation.ERASER_CLICK:
switch (OperationUtils.getInstance().mCurrentOPerationPen) {
case WhiteBoardVariable.Operation.PEN_NORMAL:
break;
case WhiteBoardVariable.Operation.PEN_CLICK:
mFabMenuSize.clearDraw();
mFabMenuSize.setAddButtonBackground(R.drawable.white_board_pen_selector);
OperationUtils.getInstance().mCurrentOPerationPen = WhiteBoardVariable.Operation.PEN_NORMAL;
break;
case WhiteBoardVariable.Operation.PEN_EXPAND:
mFabMenuSize.collapse();
mFabMenuSize.clearDraw();
mFabMenuSize.setAddButtonBackground(R.drawable.white_board_pen_selector);
OperationUtils.getInstance().mCurrentOPerationPen = WhiteBoardVariable.Operation.PEN_NORMAL;
break;
}
break;
case WhiteBoardVariable.Operation.COLOR_CLICK:
case WhiteBoardVariable.Operation.OUTSIDE_CLICK:
switch (OperationUtils.getInstance().mCurrentOPerationPen) {
case WhiteBoardVariable.Operation.PEN_NORMAL:
break;
case WhiteBoardVariable.Operation.PEN_CLICK:
break;
case WhiteBoardVariable.Operation.PEN_EXPAND:
mFabMenuSize.collapse();
OperationUtils.getInstance().mCurrentOPerationPen = WhiteBoardVariable.Operation.PEN_CLICK;
break;
}
break;
}
}
/**
* 白板工具栏点击切换操作-颜色
*/
private void setColorOperation(int currentOperation) {
switch (currentOperation) {
case WhiteBoardVariable.Operation.PEN_CLICK:
case WhiteBoardVariable.Operation.TEXT_CLICK:
case WhiteBoardVariable.Operation.ERASER_CLICK:
case WhiteBoardVariable.Operation.OUTSIDE_CLICK:
switch (OperationUtils.getInstance().mCurrentOPerationColor) {
case WhiteBoardVariable.Operation.COLOR_NORMAL:
break;
case WhiteBoardVariable.Operation.COLOR_EXPAND:
mFabMenuColor.collapse();
OperationUtils.getInstance().mCurrentOPerationColor = WhiteBoardVariable.Operation.COLOR_NORMAL;
break;
}
break;
case WhiteBoardVariable.Operation.COLOR_CLICK:
switch (OperationUtils.getInstance().mCurrentOPerationColor) {
case WhiteBoardVariable.Operation.COLOR_NORMAL:
mFabMenuColor.expand();
OperationUtils.getInstance().mCurrentOPerationColor = WhiteBoardVariable.Operation.COLOR_EXPAND;
break;
case WhiteBoardVariable.Operation.COLOR_EXPAND:
mFabMenuColor.collapse();
OperationUtils.getInstance().mCurrentOPerationColor = WhiteBoardVariable.Operation.COLOR_NORMAL;
break;
}
break;
}
}
/**
* 白板工具栏点击切换操作-文字
*/
private void setTextOperation(int currentOperation) {
switch (currentOperation) {
case WhiteBoardVariable.Operation.TEXT_CLICK:
switch (OperationUtils.getInstance().mCurrentOPerationText) {
case WhiteBoardVariable.Operation.TEXT_NORMAL:
OperationUtils.getInstance().mCurrentDrawType = OperationUtils.DRAW_TEXT;
mFabMenuText.setAddButtonBackground(R.drawable.white_board_text_selected_selector);
OperationUtils.getInstance().mCurrentOPerationText = WhiteBoardVariable.Operation.TEXT_CLICK;
break;
case WhiteBoardVariable.Operation.TEXT_CLICK:
int size = OperationUtils.getInstance().getSavePoints().size();
if (size > 0) {
DrawPoint dp = OperationUtils.getInstance().getSavePoints().get(size - 1);
if (dp.getType() == OperationUtils.DRAW_TEXT && dp.getDrawText().getStatus() == DrawTextView.TEXT_DETAIL) {
changeTextBack();
mFabMenuText.expand();
OperationUtils.getInstance().mCurrentOPerationText = WhiteBoardVariable.Operation.TEXT_EXPAND;
}
}
break;
case WhiteBoardVariable.Operation.TEXT_EXPAND:
mFabMenuText.collapse();
OperationUtils.getInstance().mCurrentOPerationText = WhiteBoardVariable.Operation.TEXT_CLICK;
break;
}
break;
case WhiteBoardVariable.Operation.PEN_CLICK:
case WhiteBoardVariable.Operation.ERASER_CLICK:
switch (OperationUtils.getInstance().mCurrentOPerationText) {
case WhiteBoardVariable.Operation.TEXT_NORMAL:
break;
case WhiteBoardVariable.Operation.TEXT_CLICK:
mFabMenuText.clearDraw();
mFabMenuText.setAddButtonBackground(R.drawable.white_board_text_selector);
OperationUtils.getInstance().mCurrentOPerationText = WhiteBoardVariable.Operation.TEXT_NORMAL;
break;
case WhiteBoardVariable.Operation.TEXT_EXPAND:
mFabMenuText.collapse();
mFabMenuText.clearDraw();
mFabMenuText.setAddButtonBackground(R.drawable.white_board_text_selector);
OperationUtils.getInstance().mCurrentOPerationText = WhiteBoardVariable.Operation.TEXT_NORMAL;
break;
}
break;
case WhiteBoardVariable.Operation.COLOR_CLICK:
case WhiteBoardVariable.Operation.OUTSIDE_CLICK:
switch (OperationUtils.getInstance().mCurrentOPerationText) {
case WhiteBoardVariable.Operation.TEXT_NORMAL:
break;
case WhiteBoardVariable.Operation.TEXT_CLICK:
break;
case WhiteBoardVariable.Operation.TEXT_EXPAND:
mFabMenuText.collapse();
OperationUtils.getInstance().mCurrentOPerationText = WhiteBoardVariable.Operation.TEXT_CLICK;
break;
}
break;
}
}
/**
* 白板工具栏点击切换操作-橡皮擦
*/
private void setEraserOperation(int currentOperation) {
switch (currentOperation) {
case WhiteBoardVariable.Operation.ERASER_CLICK:
switch (OperationUtils.getInstance().mCurrentOPerationEraser) {
case WhiteBoardVariable.Operation.ERASER_NORMAL:
OperationUtils.getInstance().mCurrentDrawType = OperationUtils.DRAW_ERASER;
mDbView.changeEraser();
mFabMenuEraser.setAddButtonBackground(R.drawable.white_board_eraser_selected_selector);
OperationUtils.getInstance().mCurrentOPerationEraser = WhiteBoardVariable.Operation.ERASER_CLICK;
break;
case WhiteBoardVariable.Operation.ERASER_CLICK:
mFabMenuEraser.expand();
changeEraserBack();
OperationUtils.getInstance().mCurrentOPerationEraser = WhiteBoardVariable.Operation.ERASER_EXPAND;
break;
case WhiteBoardVariable.Operation.ERASER_EXPAND:
mFabMenuEraser.collapse();
OperationUtils.getInstance().mCurrentOPerationEraser = WhiteBoardVariable.Operation.ERASER_CLICK;
break;
}
break;
case WhiteBoardVariable.Operation.TEXT_CLICK:
case WhiteBoardVariable.Operation.PEN_CLICK:
switch (OperationUtils.getInstance().mCurrentOPerationEraser) {
case WhiteBoardVariable.Operation.ERASER_NORMAL:
break;
case WhiteBoardVariable.Operation.ERASER_CLICK:
mFabMenuEraser.clearDraw();
mFabMenuEraser.setAddButtonBackground(R.drawable.white_board_eraser_selector);
OperationUtils.getInstance().mCurrentOPerationEraser = WhiteBoardVariable.Operation.ERASER_NORMAL;
break;
case WhiteBoardVariable.Operation.ERASER_EXPAND:
mFabMenuEraser.collapse();
mFabMenuEraser.clearDraw();
mFabMenuEraser.setAddButtonBackground(R.drawable.white_board_eraser_selector);
OperationUtils.getInstance().mCurrentOPerationEraser = WhiteBoardVariable.Operation.ERASER_NORMAL;
break;
}
break;
case WhiteBoardVariable.Operation.COLOR_CLICK:
case WhiteBoardVariable.Operation.OUTSIDE_CLICK:
switch (OperationUtils.getInstance().mCurrentOPerationEraser) {
case WhiteBoardVariable.Operation.ERASER_NORMAL:
break;
case WhiteBoardVariable.Operation.ERASER_CLICK:
break;
case WhiteBoardVariable.Operation.ERASER_EXPAND:
mFabMenuEraser.collapse();
OperationUtils.getInstance().mCurrentOPerationEraser = WhiteBoardVariable.Operation.ERASER_CLICK;
break;
}
break;
}
}
/**
* 保存当前白板为图片
*/
public void saveImage() {
String fileName = StoreUtil.getPhotoSavePath();
Log.e("gpy", fileName);
File file = new File(fileName);
try {
File directory = file.getParentFile();
if (!directory.exists() && !directory.mkdirs()) {
showMessage(getString(R.string.white_board_export_fail));
return;
}
file.createNewFile();
FileOutputStream out = new FileOutputStream(file);
mFlView.setDrawingCacheEnabled(true);
mFlView.buildDrawingCache();
Bitmap bitmap = mFlView.getDrawingCache();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
mFlView.destroyDrawingCache();
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
sendBroadcast(intent);//这个广播的目的就是更新图库
showMessage(getString(R.string.white_board_export_tip) + fileName);
} catch (Exception e) {
showMessage(getString(R.string.white_board_export_fail));
e.printStackTrace();
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
@ReceiveEvents(name = Events.WHITE_BOARD_TEXT_EDIT)
private void textEdit() {//文字编辑
mIvWhiteBoardBack.setVisibility(View.GONE);
mIvWhiteBoardExport.setVisibility(View.GONE);
mIvWhiteBoardSave.setVisibility(View.GONE);
mRlBottom.setVisibility(View.GONE);
mIvWhiteBoardDisable.setVisibility(View.GONE);
// mLayoutParams = (RelativeLayout.LayoutParams) mRlContent.getLayoutParams();
// mLayoutParams.setMargins(OperationUtils.dip2px(24), 0, OperationUtils.dip2px(24), 0);
// mRlContent.setLayoutParams(mLayoutParams);
mIvWhiteBoardQuit.setVisibility(View.VISIBLE);
mIvWhiteBoardConfirm.setVisibility(View.VISIBLE);
}
@ReceiveEvents(name = Events.WHITE_BOARD_UNDO_REDO)
private void showUndoRedo() {//是否显示撤销、重装按钮
if (OperationUtils.getInstance().getSavePoints().isEmpty()) {
mIvWhiteBoardUndo.setVisibility(View.INVISIBLE);
mIvWhiteBoardExport.setVisibility(View.INVISIBLE);
mIvWhiteBoardSave.setVisibility(View.INVISIBLE);
} else {
mIvWhiteBoardUndo.setVisibility(View.VISIBLE);
mIvWhiteBoardExport.setVisibility(View.VISIBLE);
mIvWhiteBoardSave.setVisibility(View.VISIBLE);
}
if (OperationUtils.getInstance().getDeletePoints().isEmpty()) {
mIvWhiteBoardRedo.setVisibility(View.INVISIBLE);
} else {
mIvWhiteBoardRedo.setVisibility(View.VISIBLE);
}
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/view/base/BaseActivity.java
================================================
package com.example.gpy.whiteboard.view.base;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;
import com.github.guanpy.library.EventBus;
import butterknife.ButterKnife;
/**
* Created by gpy on 2016/2/17.
*/
public abstract class BaseActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(this.getLayoutId());
ButterKnife.inject(this);
this.afterCreate(savedInstanceState);
}
protected abstract int getLayoutId();
protected abstract void afterCreate(Bundle savedInstanceState);
protected void showMessage(CharSequence msg) {
Toast.makeText(this,msg,Toast.LENGTH_SHORT).show();
}
@Override
protected void onResume() {
super.onResume();
EventBus.registerAnnotatedReceiver(this);
}
@Override
protected void onPause() {
super.onPause();
EventBus.unregisterAnnotatedReceiver(this);
}
public void navi2Page(final Class<?> page) {
this.navi2Page(page, false);
}
public void navi2Page(final Class<?> page, final boolean shut) {
this.navi2Page(page, null, shut);
}
public void navi2Page(final Class<?> page, final Bundle data, final boolean shut) {
final Intent intent = new Intent(this, page);
if (null != data) {
intent.putExtras(data);
}
this.startActivity(intent);
if (shut) {
this.finish();
}
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/view/widget/floatingactionmenu/AddFloatingActionButton.java
================================================
package com.example.gpy.whiteboard.view.widget.floatingactionmenu;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.Shape;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.util.AttributeSet;
import com.example.gpy.whiteboard.R;
public class AddFloatingActionButton extends FloatingActionButton {
int mPlusColor;
public AddFloatingActionButton(Context context) {
this(context, null);
}
public AddFloatingActionButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AddFloatingActionButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
void init(Context context, AttributeSet attributeSet) {
TypedArray attr = context.obtainStyledAttributes(attributeSet, R.styleable.AddFloatingActionButton, 0, 0);
mPlusColor = attr.getColor(R.styleable.AddFloatingActionButton_fab_plusIconColor, getColor(android.R.color.white));
attr.recycle();
super.init(context, attributeSet);
}
/**
* @return the current Color of plus icon.
*/
public int getPlusColor() {
return mPlusColor;
}
public void setPlusColorResId(@ColorRes int plusColor) {
setPlusColor(getColor(plusColor));
}
public void setPlusColor(int color) {
if (mPlusColor != color) {
mPlusColor = color;
updateBackground();
}
}
@Override
public void setIcon(@DrawableRes int icon) {
throw new UnsupportedOperationException("Use FloatingActionButton if you want to use custom icon");
}
@Override
Drawable getIconDrawable() {
final float iconSize = getDimension(R.dimen.fab_icon_size);
final float iconHalfSize = iconSize / 2f;
final float plusSize = getDimension(R.dimen.fab_plus_icon_size);
final float plusHalfStroke = getDimension(R.dimen.fab_plus_icon_stroke) / 2f;
final float plusOffset = (iconSize - plusSize) / 2f;
final Shape shape = new Shape() {
@Override
public void draw(Canvas canvas, Paint paint) {
canvas.drawRect(plusOffset, iconHalfSize - plusHalfStroke, iconSize - plusOffset, iconHalfSize + plusHalfStroke, paint);
canvas.drawRect(iconHalfSize - plusHalfStroke, plusOffset, iconHalfSize + plusHalfStroke, iconSize - plusOffset, paint);
}
};
ShapeDrawable drawable = new ShapeDrawable(shape);
final Paint paint = drawable.getPaint();
paint.setColor(mPlusColor);
paint.setStyle(Style.FILL);
paint.setAntiAlias(true);
return drawable;
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/view/widget/floatingactionmenu/FloatingActionButton.java
================================================
package com.example.gpy.whiteboard.view.widget.floatingactionmenu;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.ShapeDrawable.ShaderFactory;
import android.graphics.drawable.StateListDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.support.annotation.ColorRes;
import android.support.annotation.DimenRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.widget.TextView;
import com.example.gpy.whiteboard.R;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public class FloatingActionButton extends FloatingImageButton {
public static final int SIZE_NORMAL = 0;
public static final int SIZE_MINI = 1;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ SIZE_NORMAL, SIZE_MINI })
public @interface FAB_SIZE {
}
int mColorNormal;
int mColorPressed;
int mColorDisabled;
String mTitle;
@DrawableRes
private int mIcon;
private Drawable mIconDrawable;
private int mSize;
private float mCircleSize;
private float mShadowRadius;
private float mShadowOffset;
private int mDrawableSize;
boolean mStrokeVisible;
public FloatingActionButton(Context context) {
this(context, null);
}
public FloatingActionButton(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public FloatingActionButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
void init(Context context, AttributeSet attributeSet) {
TypedArray attr = context.obtainStyledAttributes(attributeSet, R.styleable.FloatingActionButton, 0, 0);
mColorNormal = attr.getColor(R.styleable.FloatingActionButton_fab_colorNormal, getColor(android.R.color.holo_blue_dark));
mColorPressed = attr.getColor(R.styleable.FloatingActionButton_fab_colorPressed, getColor(android.R.color.holo_blue_light));
mColorDisabled = attr.getColor(R.styleable.FloatingActionButton_fab_colorDisabled, getColor(android.R.color.darker_gray));
mSize = attr.getInt(R.styleable.FloatingActionButton_fab_size, SIZE_NORMAL);
mIcon = attr.getResourceId(R.styleable.FloatingActionButton_fab_icon, 0);
mTitle = attr.getString(R.styleable.FloatingActionButton_fab_title);
mStrokeVisible = attr.getBoolean(R.styleable.FloatingActionButton_fab_stroke_visible, true);
attr.recycle();
updateCircleSize();
mShadowRadius = getDimension(R.dimen.fab_shadow_radius);
mShadowOffset = getDimension(R.dimen.fab_shadow_offset);
updateDrawableSize();
updateBackground();
}
private void updateDrawableSize() {
mDrawableSize = (int) (mCircleSize + 2 * mShadowRadius);
}
private void updateCircleSize() {
mCircleSize = getDimension(mSize == SIZE_NORMAL ? R.dimen.fab_size_normal : R.dimen.fab_size_mini);
}
public void setSize(@FAB_SIZE int size) {
if (size != SIZE_MINI && size != SIZE_NORMAL) {
throw new IllegalArgumentException("Use @FAB_SIZE constants only!");
}
if (mSize != size) {
mSize = size;
updateCircleSize();
updateDrawableSize();
updateBackground();
}
}
@FAB_SIZE
public int getSize() {
return mSize;
}
public void setIcon(@DrawableRes int icon) {
if (mIcon != icon) {
mIcon = icon;
mIconDrawable = null;
updateBackground();
}
}
public void setIconDrawable(@NonNull Drawable iconDrawable) {
if (mIconDrawable != iconDrawable) {
mIcon = 0;
mIconDrawable = iconDrawable;
updateBackground();
}
}
/**
* @return the current Color for normal state.
*/
public int getColorNormal() {
return mColorNormal;
}
public void setColorNormalResId(@ColorRes int colorNormal) {
setColorNormal(getColor(colorNormal));
}
public void setColorNormal(int color) {
if (mColorNormal != color) {
mColorNormal = color;
updateBackground();
}
}
/**
* @return the current color for pressed state.
*/
public int getColorPressed() {
return mColorPressed;
}
public void setColorPressedResId(@ColorRes int colorPressed) {
setColorPressed(getColor(colorPressed));
}
public void setColorPressed(int color) {
if (mColorPressed != color) {
mColorPressed = color;
updateBackground();
}
}
/**
* @return the current color for disabled state.
*/
public int getColorDisabled() {
return mColorDisabled;
}
public void setColorDisabledResId(@ColorRes int colorDisabled) {
setColorDisabled(getColor(colorDisabled));
}
public void setColorDisabled(int color) {
if (mColorDisabled != color) {
mColorDisabled = color;
updateBackground();
}
}
public void setStrokeVisible(boolean visible) {
if (mStrokeVisible != visible) {
mStrokeVisible = visible;
updateBackground();
}
}
public boolean isStrokeVisible() {
return mStrokeVisible;
}
int getColor(@ColorRes int id) {
return getResources().getColor(id);
}
float getDimension(@DimenRes int id) {
return getResources().getDimension(id);
}
public void setTitle(String title) {
mTitle = title;
TextView label = getLabelView();
if (label != null) {
label.setText(title);
}
}
TextView getLabelView() {
return (TextView) getTag(R.id.fab_label);
}
public String getTitle() {
return mTitle;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(mDrawableSize, mDrawableSize);
}
void updateBackground() {
final float strokeWidth = getDimension(R.dimen.fab_stroke_width);
final float halfStrokeWidth = strokeWidth / 2f;
LayerDrawable layerDrawable = new LayerDrawable(
new Drawable[] {
getResources().getDrawable(mSize == SIZE_NORMAL ? R.drawable.fab_bg_normal : R.drawable.fab_bg_mini),
createFillDrawable(strokeWidth),
createOuterStrokeDrawable(strokeWidth),
getIconDrawable()
});
int iconOffset = (int) (mCircleSize - getDimension(R.dimen.fab_icon_size)) / 2;
int circleInsetHorizontal = (int) (mShadowRadius);
int circleInsetTop = (int) (mShadowRadius - mShadowOffset);
int circleInsetBottom = (int) (mShadowRadius + mShadowOffset);
layerDrawable.setLayerInset(1,
circleInsetHorizontal,
circleInsetTop,
circleInsetHorizontal,
circleInsetBottom);
layerDrawable.setLayerInset(2,
(int) (circleInsetHorizontal - halfStrokeWidth),
(int) (circleInsetTop - halfStrokeWidth),
(int) (circleInsetHorizontal - halfStrokeWidth),
(int) (circleInsetBottom - halfStrokeWidth));
layerDrawable.setLayerInset(3,
circleInsetHorizontal + iconOffset,
circleInsetTop + iconOffset,
circleInsetHorizontal + iconOffset,
circleInsetBottom + iconOffset);
setBackgroundCompat(layerDrawable);
}
Drawable getIconDrawable() {
if (mIconDrawable != null) {
return mIconDrawable;
} else if (mIcon != 0) {
return getResources().getDrawable(mIcon);
} else {
return new ColorDrawable(Color.TRANSPARENT);
}
}
private StateListDrawable createFillDrawable(float strokeWidth) {
StateListDrawable drawable = new StateListDrawable();
drawable.addState(new int[] { -android.R.attr.state_enabled }, createCircleDrawable(mColorDisabled, strokeWidth));
drawable.addState(new int[] { android.R.attr.state_pressed }, createCircleDrawable(mColorPressed, strokeWidth));
drawable.addState(new int[] { }, createCircleDrawable(mColorNormal, strokeWidth));
return drawable;
}
private Drawable createCircleDrawable(int color, float strokeWidth) {
int alpha = Color.alpha(color);
int opaqueColor = opaque(color);
ShapeDrawable fillDrawable = new ShapeDrawable(new OvalShape());
final Paint paint = fillDrawable.getPaint();
paint.setAntiAlias(true);
paint.setColor(opaqueColor);
Drawable[] layers = {
fillDrawable,
createInnerStrokesDrawable(opaqueColor, strokeWidth)
};
LayerDrawable drawable = alpha == 255 || !mStrokeVisible
? new LayerDrawable(layers)
: new TranslucentLayerDrawable(alpha, layers);
int halfStrokeWidth = (int) (strokeWidth / 2f);
drawable.setLayerInset(1, halfStrokeWidth, halfStrokeWidth, halfStrokeWidth, halfStrokeWidth);
return drawable;
}
private static class TranslucentLayerDrawable extends LayerDrawable {
private final int mAlpha;
public TranslucentLayerDrawable(int alpha, Drawable... layers) {
super(layers);
mAlpha = alpha;
}
@Override
public void draw(Canvas canvas) {
Rect bounds = getBounds();
canvas.saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, mAlpha, Canvas.ALL_SAVE_FLAG);
super.draw(canvas);
canvas.restore();
}
}
private Drawable createOuterStrokeDrawable(float strokeWidth) {
ShapeDrawable shapeDrawable = new ShapeDrawable(new OvalShape());
final Paint paint = shapeDrawable.getPaint();
paint.setAntiAlias(true);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(Style.STROKE);
paint.setColor(Color.BLACK);
paint.setAlpha(opacityToAlpha(0.02f));
return shapeDrawable;
}
private int opacityToAlpha(float opacity) {
return (int) (255f * opacity);
}
private int darkenColor(int argb) {
return adjustColorBrightness(argb, 0.9f);
}
private int lightenColor(int argb) {
return adjustColorBrightness(argb, 1.1f);
}
private int adjustColorBrightness(int argb, float factor) {
float[] hsv = new float[3];
Color.colorToHSV(argb, hsv);
hsv[2] = Math.min(hsv[2] * factor, 1f);
return Color.HSVToColor(Color.alpha(argb), hsv);
}
private int halfTransparent(int argb) {
return Color.argb(
Color.alpha(argb) / 2,
Color.red(argb),
Color.green(argb),
Color.blue(argb)
);
}
private int opaque(int argb) {
return Color.rgb(
Color.red(argb),
Color.green(argb),
Color.blue(argb)
);
}
private Drawable createInnerStrokesDrawable(final int color, float strokeWidth) {
if (!mStrokeVisible) {
return new ColorDrawable(Color.TRANSPARENT);
}
ShapeDrawable shapeDrawable = new ShapeDrawable(new OvalShape());
final int bottomStrokeColor = darkenColor(color);
final int bottomStrokeColorHalfTransparent = halfTransparent(bottomStrokeColor);
final int topStrokeColor = lightenColor(color);
final int topStrokeColorHalfTransparent = halfTransparent(topStrokeColor);
final Paint paint = shapeDrawable.getPaint();
paint.setAntiAlias(true);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(Style.STROKE);
shapeDrawable.setShaderFactory(new ShaderFactory() {
@Override
public Shader resize(int width, int height) {
return new LinearGradient(width / 2, 0, width / 2, height,
new int[] { topStrokeColor, topStrokeColorHalfTransparent, color, bottomStrokeColorHalfTransparent, bottomStrokeColor },
new float[] { 0f, 0.2f, 0.5f, 0.8f, 1f },
TileMode.CLAMP
);
}
});
return shapeDrawable;
}
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void setBackgroundCompat(Drawable drawable) {
if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
setBackground(drawable);
} else {
setBackgroundDrawable(drawable);
}
}
@Override
public void setVisibility(int visibility) {
TextView label = getLabelView();
if (label != null) {
label.setVisibility(visibility);
}
super.setVisibility(visibility);
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/view/widget/floatingactionmenu/FloatingActionsMenu.java
================================================
package com.example.gpy.whiteboard.view.widget.floatingactionmenu;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.gpy.whiteboard.R;
import com.github.guanpy.wblib.utils.AppContextUtil;
import com.github.guanpy.wblib.utils.WhiteBoardVariable;
public class FloatingActionsMenu extends ViewGroup {
public static final int STYLE_DEFAULT = 0;
public static final int STYLE_CUSTOM = 1;
public static final int EXPAND_UP = 0;
public static final int EXPAND_DOWN = 1;
public static final int EXPAND_LEFT = 2;
public static final int EXPAND_RIGHT = 3;
public static final int LABELS_ON_LEFT_SIDE = 0;
public static final int LABELS_ON_RIGHT_SIDE = 1;
private static final int ANIMATION_DURATION = 300;
private static final float COLLAPSED_PLUS_ROTATION = 0f;
private static final float EXPANDED_PLUS_ROTATION = 90f + 45f;
private Drawable mAddButtonBackground;
private float mAddButtonWidth;
private float mAddButtonHeight;
private int mAddButtonStyle;
private int mAddButtonPlusColor;
private int mAddButtonColorNormal;
private int mAddButtonColorPressed;
private int mAddButtonSize;
private boolean mAddButtonStrokeVisible;
private int mExpandDirection;
private int mButtonSpacing;
private int mLabelsMargin;
private int mLabelsVerticalOffset;
private boolean mExpanded;
private AnimatorSet mExpandAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
private AnimatorSet mCollapseAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
// private AddFloatingActionButton mAddButton;
private FloatingImageButton mAddButton;
private RotatingDrawable mRotatingDrawable;
private int mMaxButtonWidth;
private int mMaxButtonHeight;
private int mLabelsStyle;
private int mLabelsPosition;
private int mButtonsCount;
private TouchDelegateGroup mTouchDelegateGroup;
private OnFloatingActionsMenuUpdateListener mListener;
private OnFloatingActionsMenuClickListener mClickListener;
public interface OnFloatingActionsMenuUpdateListener {
void onMenuExpanded();
void onMenuCollapsed();
}
public FloatingActionsMenu(Context context) {
this(context, null);
}
public FloatingActionsMenu(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public FloatingActionsMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
public interface OnFloatingActionsMenuClickListener{
void addButtonLister();
}
public void setOnFloatingActionsMenuClickListener(OnFloatingActionsMenuClickListener flLister){
mClickListener = flLister;
}
/**
* 在图片中间画圆环
* @param size 圆的半径
* @param color 圆的颜色
* */
/**控制按钮外圈*/
public void drawRing(int color){
mAddButton.drawRing(WhiteBoardVariable.RingSize.LARRGE, color);
}
/**
* 清除绘画
* */
public void clearDraw(){
mAddButton.clearDraw();
}
/**
* 切换控制按钮背景图
* */
public void setAddButtonBackground(int drawable){
mAddButton.setBackgroundResource(drawable);
}
/**
* dip转px
*/
private int dip2px(float dpValue) {
final float scale = AppContextUtil.getContext().getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
private void init(Context context, AttributeSet attributeSet) {
// mButtonSpacing = (int) (getResources().getDimension(R.dimen.fab_actions_spacing) - getResources().getDimension(R.dimen.fab_shadow_radius) - getResources().getDimension(R.dimen.fab_shadow_offset));
mLabelsVerticalOffset = getResources().getDimensionPixelSize(R.dimen.fab_shadow_offset);
mTouchDelegateGroup = new TouchDelegateGroup(this);
setTouchDelegate(mTouchDelegateGroup);
TypedArray attr = context.obtainStyledAttributes(attributeSet, R.styleable.FloatingActionsMenu, 0, 0);
mButtonSpacing =dip2px(attr.getDimension(R.styleable.FloatingActionsMenu_fab_buttonSpacing, 4));
mAddButtonBackground = attr.getDrawable(R.styleable.FloatingActionsMenu_fab_addButtonBackground);
mAddButtonWidth = attr.getDimension(R.styleable.FloatingActionsMenu_fab_addButtonWidth, 0);
mAddButtonHeight = attr.getDimension(R.styleable.FloatingActionsMenu_fab_addButtonHeight, 0);
mAddButtonStyle = attr.getInt(R.styleable.FloatingActionsMenu_fab_addButtonStyle, STYLE_DEFAULT);
mAddButtonPlusColor = attr.getColor(R.styleable.FloatingActionsMenu_fab_addButtonPlusIconColor, getColor(android.R.color.white));
mAddButtonColorNormal = attr.getColor(R.styleable.FloatingActionsMenu_fab_addButtonColorNormal, getColor(android.R.color.holo_blue_dark));
mAddButtonColorPressed = attr.getColor(R.styleable.FloatingActionsMenu_fab_addButtonColorPressed, getColor(android.R.color.holo_blue_light));
mAddButtonSize = attr.getInt(R.styleable.FloatingActionsMenu_fab_addButtonSize, FloatingActionButton.SIZE_NORMAL);
mAddButtonStrokeVisible = attr.getBoolean(R.styleable.FloatingActionsMenu_fab_addButtonStrokeVisible, true);
mExpandDirection = attr.getInt(R.styleable.FloatingActionsMenu_fab_expandDirection, EXPAND_UP);
mLabelsStyle = attr.getResourceId(R.styleable.FloatingActionsMenu_fab_labelStyle, 0);
mLabelsPosition = attr.getInt(R.styleable.FloatingActionsMenu_fab_labelsPosition, LABELS_ON_LEFT_SIDE);
attr.recycle();
if (mLabelsStyle != 0 && expandsHorizontally()) {
throw new IllegalStateException("Action labels in horizontal expand orientation is not supported.");
}
createAddButton(context);
}
public void setOnFloatingActionsMenuUpdateListener(OnFloatingActionsMenuUpdateListener listener) {
mListener = listener;
}
private boolean expandsHorizontally() {
return mExpandDirection == EXPAND_LEFT || mExpandDirection == EXPAND_RIGHT;
}
private static class RotatingDrawable extends LayerDrawable {
public RotatingDrawable(Drawable drawable) {
super(new Drawable[]{drawable});
}
private float mRotation;
@SuppressWarnings("UnusedDeclaration")
public float getRotation() {
return mRotation;
}
@SuppressWarnings("UnusedDeclaration")
public void setRotation(float rotation) {
mRotation = rotation;
invalidateSelf();
}
@Override
public void draw(Canvas canvas) {
canvas.save();
canvas.rotate(mRotation, getBounds().centerX(), getBounds().centerY());
super.draw(canvas);
canvas.restore();
}
}
/**
* 增加菜单的控制按钮
*/
private void createAddButton(Context context) {
if (mAddButtonStyle == STYLE_DEFAULT) {
mAddButton = new AddFloatingActionButton(context) {
@Override
void updateBackground() {
mPlusColor = mAddButtonPlusColor;
mColorNormal = mAddButtonColorNormal;
mColorPressed = mAddButtonColorPressed;
mStrokeVisible = mAddButtonStrokeVisible;
super.updateBackground();
}
@Override
Drawable getIconDrawable() {
final RotatingDrawable rotatingDrawable = new RotatingDrawable(super.getIconDrawable());
mRotatingDrawable = rotatingDrawable;
final OvershootInterpolator interpolator = new OvershootInterpolator();
final ObjectAnimator collapseAnimator = ObjectAnimator.ofFloat(rotatingDrawable, "rotation", EXPANDED_PLUS_ROTATION, COLLAPSED_PLUS_ROTATION);
final ObjectAnimator expandAnimator = ObjectAnimator.ofFloat(rotatingDrawable, "rotation", COLLAPSED_PLUS_ROTATION, EXPANDED_PLUS_ROTATION);
collapseAnimator.setInterpolator(interpolator);
expandAnimator.setInterpolator(interpolator);
mExpandAnimation.play(expandAnimator);
mCollapseAnimation.play(collapseAnimator);
return rotatingDrawable;
}
};
mAddButton.setId(R.id.fab_expand_menu_button);
((AddFloatingActionButton) mAddButton).setSize(mAddButtonSize);
} else if (mAddButtonStyle == STYLE_CUSTOM) {
mAddButton = new FloatingImageButton(context);
mAddButton.setId(R.id.fab_expand_menu_button);
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(dip2px(mAddButtonWidth), dip2px(mAddButtonHeight));
mAddButton.setLayoutParams(layoutParams);
mAddButton.setBackgroundDrawable(mAddButtonBackground);
mAddButton.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
mAddButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(null!=mClickListener){
mClickListener.addButtonLister();
}else{
toggle();
}
}
});
addView(mAddButton, super.generateDefaultLayoutParams());
}
private int getColor(@ColorRes int id) {
return getResources().getColor(id);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
int width = 0;
int height = 0;
mMaxButtonWidth = 0;
mMaxButtonHeight = 0;
int maxLabelWidth = 0;
for (int i = 0; i < mButtonsCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
switch (mExpandDirection) {
case EXPAND_UP:
case EXPAND_DOWN:
mMaxButtonWidth = Math.max(mMaxButtonWidth, child.getMeasuredWidth());
height += child.getMeasuredHeight();
break;
case EXPAND_LEFT:
case EXPAND_RIGHT:
width += child.getMeasuredWidth();
mMaxButtonHeight = Math.max(mMaxButtonHeight, child.getMeasuredHeight());
break;
}
if (!expandsHorizontally()) {
TextView label = (TextView) child.getTag(R.id.fab_label);
if (label != null) {
maxLabelWidth = Math.max(maxLabelWidth, label.getMeasuredWidth());
}
}
}
if (!expandsHorizontally()) {
width = mMaxButtonWidth + (maxLabelWidth > 0 ? maxLabelWidth + mLabelsMargin : 0);
} else {
height = mMaxButtonHeight;
}
switch (mExpandDirection) {
case EXPAND_UP:
case EXPAND_DOWN:
height += mButtonSpacing * (getChildCount() - 1);
height = adjustForOvershoot(height);
break;
case EXPAND_LEFT:
case EXPAND_RIGHT:
width += mButtonSpacing * (getChildCount() - 1);
width = adjustForOvershoot(width);
break;
}
setMeasuredDimension(width, height);
}
private int adjustForOvershoot(int dimension) {
return dimension * 12 / 10;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
switch (mExpandDirection) {
case EXPAND_UP:
case EXPAND_DOWN:
boolean expandUp = mExpandDirection == EXPAND_UP;
if (changed) {
mTouchDelegateGroup.clearTouchDelegates();
}
int addButtonY = expandUp ? b - t - mAddButton.getMeasuredHeight() : 0;
// Ensure mAddButton is centered on the line where the buttons should be
int buttonsHorizontalCenter = mLabelsPosition == LABELS_ON_LEFT_SIDE
? r - l - mMaxButtonWidth / 2
: mMaxButtonWidth / 2;
int addButtonLeft = buttonsHorizontalCenter - mAddButton.getMeasuredWidth() / 2;
mAddButton.layout(addButtonLeft, addButtonY, addButtonLeft + mAddButton.getMeasuredWidth(), addButtonY + mAddButton.getMeasuredHeight());
int labelsOffset = mMaxButtonWidth / 2 + mLabelsMargin;
int labelsXNearButton = mLabelsPosition == LABELS_ON_LEFT_SIDE
? buttonsHorizontalCenter - labelsOffset
: buttonsHorizontalCenter + labelsOffset;
int nextY = expandUp ?
addButtonY - mButtonSpacing :
addButtonY + mAddButton.getMeasuredHeight() + mButtonSpacing;
for (int i = mButtonsCount - 1; i >= 0; i--) {
final View child = getChildAt(i);
if (child == mAddButton || child.getVisibility() == GONE) continue;
int childX = buttonsHorizontalCenter - child.getMeasuredWidth() / 2;
int childY = expandUp ? nextY - child.getMeasuredHeight() : nextY;
child.layout(childX, childY, childX + child.getMeasuredWidth(), childY + child.getMeasuredHeight());
float collapsedTranslation = addButtonY - childY;
float expandedTranslation = 0f;
child.setTranslationY(mExpanded ? expandedTranslation : collapsedTranslation);
child.setAlpha(mExpanded ? 1f : 0f);
LayoutParams params = (LayoutParams) child.getLayoutParams();
params.mCollapseDir.setFloatValues(expandedTranslation, collapsedTranslation);
params.mExpandDir.setFloatValues(collapsedTranslation, expandedTranslation);
params.setAnimationsTarget(child);
View label = (View) child.getTag(R.id.fab_label);
if (label != null) {
int labelXAwayFromButton = mLabelsPosition == LABELS_ON_LEFT_SIDE
? labelsXNearButton - label.getMeasuredWidth()
: labelsXNearButton + label.getMeasuredWidth();
int labelLeft = mLabelsPosition == LABELS_ON_LEFT_SIDE
? labelXAwayFromButton
: labelsXNearButton;
int labelRight = mLabelsPosition == LABELS_ON_LEFT_SIDE
? labelsXNearButton
: labelXAwayFromButton;
int labelTop = childY - mLabelsVerticalOffset + (child.getMeasuredHeight() - label.getMeasuredHeight()) / 2;
label.layout(labelLeft, labelTop, labelRight, labelTop + label.getMeasuredHeight());
Rect touchArea = new Rect(
Math.min(childX, labelLeft),
childY - mButtonSpacing / 2,
Math.max(childX + child.getMeasuredWidth(), labelRight),
childY + child.getMeasuredHeight() + mButtonSpacing / 2);
mTouchDelegateGroup.addTouchDelegate(new TouchDelegate(touchArea, child));
label.setTranslationY(mExpanded ? expandedTranslation : collapsedTranslation);
label.setAlpha(mExpanded ? 1f : 0f);
LayoutParams labelParams = (LayoutParams) label.getLayoutParams();
labelParams.mCollapseDir.setFloatValues(expandedTranslation, collapsedTranslation);
labelParams.mExpandDir.setFloatValues(collapsedTranslation, expandedTranslation);
labelParams.setAnimationsTarget(label);
}
nextY = expandUp ?
childY - mButtonSpacing :
childY + child.getMeasuredHeight() + mButtonSpacing;
}
break;
case EXPAND_LEFT:
case EXPAND_RIGHT:
boolean expandLeft = mExpandDirection == EXPAND_LEFT;
int addButtonX = expandLeft ? r - l - mAddButton.getMeasuredWidth() : 0;
// Ensure mAddButton is centered on the line where the buttons should be
int addButtonTop = b - t - mMaxButtonHeight + (mMaxButtonHeight - mAddButton.getMeasuredHeight()) / 2;
mAddButton.layout(addButtonX, addButtonTop, addButtonX + mAddButton.getMeasuredWidth(), addButtonTop + mAddButton.getMeasuredHeight());
int nextX = expandLeft ?
addButtonX - mButtonSpacing :
addButtonX + mAddButton.getMeasuredWidth() + mButtonSpacing;
for (int i = mButtonsCount - 1; i >= 0; i--) {
final View child = getChildAt(i);
if (child == mAddButton || child.getVisibility() == GONE) continue;
int childX = expandLeft ? nextX - child.getMeasuredWidth() : nextX;
int childY = addButtonTop + (mAddButton.getMeasuredHeight() - child.getMeasuredHeight()) / 2;
child.layout(childX, childY, childX + child.getMeasuredWidth(), childY + child.getMeasuredHeight());
float collapsedTranslation = addButtonX - childX;
float expandedTranslation = 0f;
child.setTranslationX(mExpanded ? expandedTranslation : collapsedTranslation);
child.setAlpha(mExpanded ? 1f : 0f);
LayoutParams params = (LayoutParams) child.getLayoutParams();
params.mCollapseDir.setFloatValues(expandedTranslation, collapsedTranslation);
params.mExpandDir.setFloatValues(collapsedTranslation, expandedTranslation);
params.setAnimationsTarget(child);
nextX = expandLeft ?
childX - mButtonSpacing :
childX + child.getMeasuredWidth() + mButtonSpacing;
}
break;
}
}
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(super.generateDefaultLayoutParams());
}
@Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(super.generateLayoutParams(attrs));
}
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(super.generateLayoutParams(p));
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return super.checkLayoutParams(p);
}
private static Interpolator sExpandInterpolator = new OvershootInterpolator();
private static Interpolator sCollapseInterpolator = new DecelerateInterpolator(3f);
private static Interpolator sAlphaExpandInterpolator = new DecelerateInterpolator();
private class LayoutParams extends ViewGroup.LayoutParams {
private ObjectAnimator mExpandDir = new ObjectAnimator();
private ObjectAnimator mExpandAlpha = new ObjectAnimator();
private ObjectAnimator mCollapseDir = new ObjectAnimator();
private ObjectAnimator mCollapseAlpha = new ObjectAnimator();
private boolean animationsSetToPlay;
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
mExpandDir.setInterpolator(sExpandInterpolator);
mExpandAlpha.setInterpolator(sAlphaExpandInterpolator);
mCollapseDir.setInterpolator(sCollapseInterpolator);
mCollapseAlpha.setInterpolator(sCollapseInterpolator);
mCollapseAlpha.setProperty(View.ALPHA);
mCollapseAlpha.setFloatValues(1f, 0f);
mExpandAlpha.setProperty(View.ALPHA);
mExpandAlpha.setFloatValues(0f, 1f);
switch (mExpandDirection) {
case EXPAND_UP:
case EXPAND_DOWN:
mCollapseDir.setProperty(View.TRANSLATION_Y);
mExpandDir.setProperty(View.TRANSLATION_Y);
break;
case EXPAND_LEFT:
case EXPAND_RIGHT:
mCollapseDir.setProperty(View.TRANSLATION_X);
mExpandDir.setProperty(View.TRANSLATION_X);
break;
}
}
public void setAnimationsTarget(View view) {
mCollapseAlpha.setTarget(view);
mCollapseDir.setTarget(view);
mExpandAlpha.setTarget(view);
mExpandDir.setTarget(view);
// Now that the animations have targets, set them to be played
if (!animationsSetToPlay) {
mCollapseAnimation.play(mCollapseAlpha);
mCollapseAnimation.play(mCollapseDir);
mExpandAnimation.play(mExpandAlpha);
mExpandAnimation.play(mExpandDir);
animationsSetToPlay = true;
}
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
bringChildToFront(mAddButton);
mButtonsCount = getChildCount();
}
public void collapse() {
if (mExpanded) {
mExpanded = false;
mTouchDelegateGroup.setEnabled(false);
mCollapseAnimation.start();
mExpandAnimation.cancel();
if (mListener != null) {
mListener.onMenuCollapsed();
}
}
}
public void toggle() {
if (mExpanded) {
collapse();
} else {
expand();
}
}
public void expand() {
if (!mExpanded) {
mExpanded = true;
mTouchDelegateGroup.setEnabled(true);
mCollapseAnimation.cancel();
mExpandAnimation.start();
if (mListener != null) {
mListener.onMenuExpanded();
}
}
}
public boolean isExpanded() {
return mExpanded;
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.mExpanded = mExpanded;
return savedState;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
if (state instanceof SavedState) {
SavedState savedState = (SavedState) state;
mExpanded = savedState.mExpanded;
mTouchDelegateGroup.setEnabled(mExpanded);
if (mRotatingDrawable != null) {
mRotatingDrawable.setRotation(mExpanded ? EXPANDED_PLUS_ROTATION : COLLAPSED_PLUS_ROTATION);
}
super.onRestoreInstanceState(savedState.getSuperState());
} else {
super.onRestoreInstanceState(state);
}
}
public static class SavedState extends BaseSavedState {
public boolean mExpanded;
public SavedState(Parcelable parcel) {
super(parcel);
}
private SavedState(Parcel in) {
super(in);
mExpanded = in.readInt() == 1;
}
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(mExpanded ? 1 : 0);
}
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/view/widget/floatingactionmenu/FloatingImageButton.java
================================================
package com.example.gpy.whiteboard.view.widget.floatingactionmenu;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.ImageButton;
import com.github.guanpy.wblib.utils.OperationUtils;
import com.github.guanpy.wblib.utils.WhiteBoardVariable;
/**
* FloatingActionButton 不具备的功能
*/
public class FloatingImageButton extends ImageButton {
Paint mPaint;
/**不做绘画操作*/
static final int DRAW_NULL = 0;
/**画圆环*/
static final int DRAW_RING = 1;
/**画圆*/
static final int DRAW_CIRCLE= 2;
/**画圆和圆环*/
static final int DRAW_CIRCLE_AND_RING= 3;
int mDrawType ;
public FloatingImageButton(Context context) {
this(context, null);
}
public FloatingImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public FloatingImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context){
mPaint = new Paint();
mPaint.setAntiAlias(true); //消除锯齿
}
/**
* 在图片中间画圆环(按钮小圆环)
* @param color 圆的颜色
* */
public void drawMiniRing(int color){
drawRing(WhiteBoardVariable.RingSize.MINI, color);
}
/**
* 在图片中间画圆环(按钮大圆环)
* @param color 圆的颜色
* */
public void drawLargeRing(int color){
drawRing(WhiteBoardVariable.RingSize.LARRGE, color);
}
/**
* 在图片中间画圆环
* @param size 圆的半径
* @param color 圆的颜色
* */
public void drawRing(int size,int color){
mPaint.setColor(color);
mPaint.setStrokeWidth(size);
mPaint.setStyle(Paint.Style.STROKE); //绘制空心圆
mDrawType = DRAW_RING;
postInvalidate();
}
/**
* 在图片中间画圆
* @param size 圆的半径
* */
public void drawCircle(int size){
drawCircle(size, OperationUtils.getInstance().mCurrentColor);
}
/**
* 在图片中间画圆
* @param size 圆的半径
* @param color 圆的颜色
* */
public void drawCircle(int size,int color){
mPaint.setColor(color);
mPaint.setStrokeWidth(size);
mPaint.setStyle(Paint.Style.FILL); //绘制实心圆
mDrawType = DRAW_CIRCLE;
postInvalidate();
}
/**
* 在图片中间画圆和外圈圆环
* @param size 圆的半径
* @param color 圆的颜色
* */
public void drawCircleAndRing(int size,int color){
mPaint.setColor(color);
mPaint.setStrokeWidth(size);
mPaint.setStyle(Paint.Style.FILL); //绘制实心圆
mDrawType = DRAW_CIRCLE_AND_RING;
postInvalidate();
}
/**
* 清除绘画
* */
public void clearDraw(){
mDrawType = DRAW_NULL;
postInvalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int center = getWidth()/2;
if(mDrawType==DRAW_RING){
canvas.drawCircle(center, center, center - mPaint.getStrokeWidth(),mPaint);
}else if(mDrawType==DRAW_CIRCLE){
canvas.drawCircle(center, center, mPaint.getStrokeWidth(),mPaint);
}else if(mDrawType==DRAW_CIRCLE_AND_RING){
canvas.drawCircle(center, center, mPaint.getStrokeWidth(), mPaint);
mPaint.setStrokeWidth(WhiteBoardVariable.RingSize.MINI);
mPaint.setStyle(Paint.Style.STROKE); //绘制空心圆
canvas.drawCircle(center, center, center - WhiteBoardVariable.RingSize.MINI, mPaint);
}
}
}
================================================
FILE: app/src/main/java/com/example/gpy/whiteboard/view/widget/floatingactionmenu/TouchDelegateGroup.java
================================================
package com.example.gpy.whiteboard.view.widget.floatingactionmenu;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.view.MotionEvent;
import android.view.TouchDelegate;
import android.view.View;
import java.util.ArrayList;
public class TouchDelegateGroup extends TouchDelegate {
private static final Rect USELESS_HACKY_RECT = new Rect();
private final ArrayList<TouchDelegate> mTouchDelegates = new ArrayList<TouchDelegate>();
private TouchDelegate mCurrentTouchDelegate;
private boolean mEnabled;
public TouchDelegateGroup(View uselessHackyView) {
super(USELESS_HACKY_RECT, uselessHackyView);
}
public void addTouchDelegate(@NonNull TouchDelegate touchDelegate) {
mTouchDelegates.add(touchDelegate);
}
public void removeTouchDelegate(TouchDelegate touchDelegate) {
mTouchDelegates.remove(touchDelegate);
if (mCurrentTouchDelegate == touchDelegate) {
mCurrentTouchDelegate = null;
}
}
public void clearTouchDelegates() {
mTouchDelegates.clear();
mCurrentTouchDelegate = null;
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
if (!mEnabled) return false;
TouchDelegate delegate = null;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
for (int i = 0; i < mTouchDelegates.size(); i++) {
TouchDelegate touchDelegate = mTouchDelegates.get(i);
if (touchDelegate.onTouchEvent(event)) {
mCurrentTouchDelegate = touchDelegate;
return true;
}
}
break;
case MotionEvent.ACTION_MOVE:
delegate = mCurrentTouchDelegate;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
delegate = mCurrentTouchDelegate;
mCurrentTouchDelegate = null;
break;
}
return delegate != null && delegate.onTouchEvent(event);
}
public void setEnabled(boolean enabled) {
mEnabled = enabled;
}
}
================================================
FILE: app/src/main/res/drawable/bg_white_board.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white"/>
<corners android:radius="4dp"/>
</shape>
================================================
FILE: app/src/main/res/drawable/common_cancel_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/common_cancel_click"/>
<item android:state_focused="true" android:drawable="@drawable/common_cancel_click" />
<item android:state_pressed="false" android:drawable="@drawable/common_cancel_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/common_confirm_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/common_confirm_click"/>
<item android:state_focused="true" android:drawable="@drawable/common_confirm_click" />
<item android:state_pressed="false" android:drawable="@drawable/common_confirm_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/draw_text_border.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="@color/white_board_drawtext_back" />
<stroke android:width="0.5dip" android:color="@color/grey_3e"/>
</shape>
================================================
FILE: app/src/main/res/drawable/fab_label_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/black_semi_transparent"/>
<padding
android:left="16dp"
android:top="4dp"
android:right="16dp"
android:bottom="4dp"/>
<corners
android:radius="2dp"/>
</shape>
================================================
FILE: app/src/main/res/drawable/ic_back_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/ic_back_pressed"/>
<item android:state_focused="true" android:drawable="@drawable/ic_back_pressed"/>
<item android:drawable="@drawable/ic_back_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_add_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_add_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_add_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_add_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_color_black_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_color_black_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_color_black_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_color_black_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_color_green_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_color_green_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_color_green_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_color_green_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_color_orange_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_color_orange_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_color_orange_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_color_orange_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_color_pink_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_color_pink_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_color_pink_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_color_pink_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_color_purple_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_color_purple_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_color_purple_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_color_purple_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_disable_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_disable_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_disable_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_disable_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_eraser_selected_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_eraser_selected_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_eraser_selected_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_eraser_selected_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_eraser_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_eraser_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_eraser_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_eraser_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_export_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_export_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_export_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_export_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_next_page_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_next_page_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_next_page_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_next_page_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_pen_selected_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_pen_selected_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_pen_selected_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_pen_selected_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_pen_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_pen_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_pen_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_pen_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_pre_page_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_pre_page_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_pre_page_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_pre_page_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_redo_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_redo_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_redo_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_redo_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_save_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_save_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_save_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_save_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_text_bold_selected_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_text_bold_selected_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_text_bold_selected_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_text_bold_selected_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_text_bold_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_text_bold_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_text_bold_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_text_bold_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_text_italics_selected_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_text_italics_selected_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_text_italics_selected_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_text_italics_selected_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_text_italics_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_text_italics_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_text_italics_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_text_italics_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_text_selected_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_text_selected_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_text_selected_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_text_selected_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_text_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_text_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_text_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_text_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_text_underline_selected_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_text_underline_selected_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_text_underline_selected_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_text_underline_selected_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_text_underline_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_text_underline_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_text_underline_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_text_underline_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_undisable_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_undisable_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_undisable_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_undisable_normal"/>
</selector>
================================================
FILE: app/src/main/res/drawable/white_board_undo_selector.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/white_board_undo_click"/>
<item android:state_focused="true" android:drawable="@drawable/white_board_undo_click" />
<item android:state_pressed="false" android:drawable="@drawable/white_board_undo_normal"/>
</selector>
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/colorPrimary">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/app_list"
android:textColor="@color/white"
android:textSize="20sp" />
<ImageView
android:id="@+id/iv_wb_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="24dip"
android:src="@drawable/ic_wb_add" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_list_loading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/app_list_loading"
android:gravity="center"
android:visibility="gone"
android:textSize="20sp" />
<ListView
android:id="@+id/lv_wb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:divider="@color/colorDivide"
android:dividerHeight="1dp"
android:listSelector="@null" />
</RelativeLayout>
</LinearLayout>
================================================
FILE: app/src/main/res/layout/activity_white_board.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_white_board_book"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/cover" />
</FrameLayout>
<RelativeLayout
android:id="@+id/rl_head"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp">
<ImageView
android:id="@+id/iv_white_board_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/ic_back_selector" />
<ImageView
android:id="@+id/iv_white_board_quit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/common_cancel_selector"
android:visibility="gone" />
<TextView
android:id="@+id/tv_white_board_head"
style="@style/HeaderTextView"
android:layout_centerInParent="true"
android:text="@string/white_board_name" />
<ImageView
android:id="@+id/iv_white_board_confirm"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/common_confirm_selector"
android:visibility="gone" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_marginRight="60dp">
<ImageView
android:id="@+id/iv_white_board_export"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_gravity="center_vertical"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/white_board_save_selector" />
<ImageView
android:id="@+id/iv_white_board_save"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_gravity="center_vertical"
android:layout_marginLeft="30dp"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/white_board_export_selector" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/rl_head"
android:layout_marginBottom="24dp"
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp">
<ScrollView
android:id="@+id/sv_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:fadingEdge="none"
android:scrollbars="none"
>
<FrameLayout
android:id="@+id/fl_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_white_board"
>
<com.github.guanpy.wblib.widget.DrawPenView
android:id="@+id/db_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<com.github.guanpy.wblib.widget.DrawTextLayout
android:id="@+id/dt_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
</ScrollView>
<RelativeLayout
android:id="@+id/rl_bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<View
android:id="@+id/v_bottom_back"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:background="@color/transparent" />
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingActionsMenu
android:id="@+id/fab_menu_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
fab:fab_addButtonBackground="@drawable/white_board_pen_selector"
fab:fab_addButtonHeight="44dip"
fab:fab_addButtonStyle="customStyle"
fab:fab_addButtonWidth="44dip"
fab:fab_buttonSpacing="12dp"
fab:fab_expandDirection="up"
fab:fab_labelStyle="@style/menu_labels_style">
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_size_large"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_drable_back_normal" />
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_size_middle"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_drable_back_normal" />
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_size_mini"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_drable_back_normal" />
</com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingActionsMenu>
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingActionsMenu
android:id="@+id/fab_menu_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="16dp"
android:layout_marginLeft="12dp"
android:layout_toRightOf="@+id/fab_menu_size"
fab:fab_addButtonBackground="@drawable/white_board_color_black_selector"
fab:fab_addButtonHeight="44dip"
fab:fab_addButtonStyle="customStyle"
fab:fab_addButtonWidth="44dip"
fab:fab_buttonSpacing="12dp"
fab:fab_expandDirection="up"
fab:fab_labelStyle="@style/menu_labels_style">
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_color_green"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_color_green_selector" />
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_color_purple"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_color_purple_selector" />
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_color_pink"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_color_pink_selector" />
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_color_orange"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_color_orange_selector" />
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_color_black"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_color_black_selector" />
</com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingActionsMenu>
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingActionsMenu
android:id="@+id/fab_menu_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="16dp"
android:layout_marginLeft="12dp"
android:layout_toRightOf="@+id/fab_menu_color"
fab:fab_addButtonBackground="@drawable/white_board_text_selector"
fab:fab_addButtonHeight="44dip"
fab:fab_addButtonStyle="customStyle"
fab:fab_addButtonWidth="44dip"
fab:fab_buttonSpacing="12dp"
fab:fab_expandDirection="up"
fab:fab_labelStyle="@style/menu_labels_style">
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_text_underline"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_text_underline_selector" />
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_text_italics"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_text_italics_selector"
android:visibility="gone" />
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_text_bold"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_text_bold_selector" />
</com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingActionsMenu>
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingActionsMenu
android:id="@+id/fab_menu_eraser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="16dp"
android:layout_marginLeft="12dp"
android:layout_toRightOf="@+id/fab_menu_text"
fab:fab_addButtonBackground="@drawable/white_board_eraser_selector"
fab:fab_addButtonHeight="44dip"
fab:fab_addButtonStyle="customStyle"
fab:fab_addButtonWidth="44dip"
fab:fab_buttonSpacing="12dp"
fab:fab_expandDirection="up"
fab:fab_labelStyle="@style/menu_labels_style">
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_eraser_large"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_drable_back_normal" />
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_eraser_middle"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_drable_back_normal" />
<com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingImageButton
android:id="@+id/bt_eraser_mini"
android:layout_width="44dip"
android:layout_height="44dip"
android:background="@drawable/white_board_drable_back_normal" />
</com.example.gpy.whiteboard.view.widget.floatingactionmenu.FloatingActionsMenu>
<ImageView
android:id="@+id/iv_white_board_undo"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_alignParentBottom="true"
android:layout_gravity="center_vertical"
android:layout_marginBottom="16dp"
android:layout_marginLeft="12dp"
android:layout_toRightOf="@+id/fab_menu_eraser"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/white_board_undo_selector" />
<ImageView
android:id="@+id/iv_white_board_redo"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_alignParentBottom="true"
android:layout_gravity="center_vertical"
android:layout_marginBottom="16dp"
android:layout_marginLeft="12dp"
android:layout_toRightOf="@+id/iv_white_board_undo"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/white_board_redo_selector" />
<LinearLayout
android:id="@+id/ll_white_board_page"
android:layout_width="wrap_content"
android:layout_height="44dip"
android:layout_alignParentBottom="true"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:layout_toLeftOf="@+id/iv_white_board_add"
android:background="@drawable/white_board_page_back"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/ll_white_board_pre"
android:layout_width="wrap_content"
android:layout_height="44dip"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_white_board_pre"
android:layout_width="7dp"
android:layout_height="14dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dip"
android:layout_marginRight="10dip"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/white_board_pre_page_selector" />
</LinearLayout>
<TextView
android:id="@+id/tv_white_board_page"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:text="1/3"
android:textColor="@color/primary_black" />
<LinearLayout
android:id="@+id/ll_white_board_next"
android:layout_width="wrap_content"
android:layout_height="44dip"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_white_board_next"
android:layout_width="7dp"
android:layout_height="14dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dip"
android:layout_marginRight="16dip"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/white_board_next_page_selector" />
</LinearLayout>
</LinearLayout>
<ImageView
android:id="@+id/iv_white_board_add"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_alignParentBottom="true"
android:layout_gravity="center_vertical"
android:layout_marginBottom="16dp"
android:layout_marginRight="76dp"
android:layout_alignParentRight="true"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/white_board_add_selector" />
</RelativeLayout>
<ImageView
android:id="@+id/iv_white_board_disable"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_gravity="center_vertical"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/white_board_disable_selector" />
</RelativeLayout>
</RelativeLayout>
================================================
FILE: app/src/main/res/layout/draw_text.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent" >
<View
android:id="@+id/v_outside"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent" />
<RelativeLayout
android:id="@+id/rl_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RelativeLayout
android:id="@+id/rl_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dip"
android:layout_marginRight="15dip"
android:background="@drawable/draw_text_border"
android:gravity="center_vertical"
android:paddingTop="25dip"
android:paddingBottom="25dip"
android:paddingLeft="30dip"
android:paddingRight="30dip" >
<EditText
android:id="@+id/et_text_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:minWidth="20dip"
android:textSize="24sp"
android:singleLine="true"
android:visibility="gone" />
<TextView
android:id="@+id/tv_text_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:minWidth="20dip"
android:textSize="24sp"
android:singleLine="true"
android:clickable="true"
android:visibility="visible" />
</RelativeLayout>
<Button
android:id="@+id/bt_text_delete"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/draw_text_delete" />
<Button
android:id="@+id/bt_text_edit"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_centerVertical="true"
android:layout_marginLeft="-30dip"
android:layout_toRightOf="@+id/rl_text"
android:background="@drawable/draw_text_edit" />
</RelativeLayout>
</RelativeLayout>
================================================
FILE: app/src/main/res/layout/wb_item.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_wb_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:textSize="19sp" />
</LinearLayout>
</FrameLayout>
================================================
FILE: app/src/main/res/values/attrs.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="FloatingActionButton">
<attr name="fab_colorPressed" format="color"/>
<attr name="fab_colorDisabled" format="color"/>
<attr name="fab_colorNormal" format="color"/>
<attr name="fab_icon" format="reference"/>
<attr name="fab_size" format="enum">
<enum name="normal" value="0"/>
<enum name="mini" value="1"/>
</attr>
<attr name="fab_title" format="string"/>
<attr name="fab_stroke_visible" format="boolean"/>
</declare-styleable>
<declare-styleable name="AddFloatingActionButton">
<attr name="fab_plusIconColor" format="color"/>
</declare-styleable>
<declare-styleable name="FloatingActionsMenu">
<attr name="fab_buttonSpacing" format="dimension"/>
<attr name="fab_addButtonColorPressed" format="color"/>
<attr name="fab_addButtonColorNormal" format="color"/>
<attr name="fab_addButtonSize" format="enum">
<enum name="normal" value="0"/>
<enum name="mini" value="1"/>
</attr>
<attr name="fab_addButtonPlusIconColor" format="color"/>
<attr name="fab_addButtonStrokeVisible" format="boolean"/>
<attr name="fab_addButtonStyle" format="enum">
<enum name="defaultStyle" value="0"/>
<enum name="customStyle" value="1"/>
</attr>
<attr name="fab_addButtonBackground" format="reference"/>
<attr name="fab_addButtonWidth" format="dimension"/>
<attr name="fab_addButtonHeight" format="dimension"/>
<attr name="fab_labelStyle" format="reference"/>
<attr name="fab_labelsPosition" format="enum">
<enum name="left" value="0"/>
<enum name="right" value="1"/>
</attr>
<attr name="fab_expandDirection" format="enum">
<enum name="up" value="0"/>
<enum name="down" value="1"/>
<enum name="left" value="2"/>
<enum name="right" value="3"/>
</attr>
</declare-styleable>
</resources>
================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="colorDivide">#DDDDDD</color>
<color name="white">#ffffff</color>
<color name="transparent">#00000000</color>
<color name="transparent_50">#7f000000</color>
<color name="cover">#cc2c1670</color>
<color name="black_semi_transparent">#B2000000</color>
<color name="primary_black">#3e3e3e</color>
<color name="grey_3e">#3e3e3e</color>
<color name="orange">#ff6a00</color>
<color name="light_red">#f54983</color>
<color name="primary_purple">#663fde</color>
<color name="green">#24a8a3</color>
<color name="white_board_drawtext_back">#f7f7f7</color>
</resources>
================================================
FILE: app/src/main/res/values/dimens.xml
================================================
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="font_200px">100sp</dimen>
<dimen name="font_160px">80sp</dimen>
<dimen name="font_80px">40sp</dimen>
<dimen name="font_72px">36sp</dimen>
<dimen name="font_60px">30sp</dimen>
<dimen name="font_44px">22sp</dimen>
<dimen name="font_40px">20sp</dimen>
<dimen name="font_36px">18sp</dimen>
<dimen name="font_32px">16sp</dimen>
<dimen name="font_30px">15sp</dimen>
<dimen name="font_28px">14sp</dimen>
<dimen name="font_24px">12sp</dimen>
<dimen name="font_22px">11sp</dimen>
<dimen name="font_20px">10sp</dimen>
<dimen name="fab_size_normal">56dp</dimen>
<dimen name="fab_size_mini">30dp</dimen>
<dimen name="fab_icon_size">24dp</dimen>
<dimen name="fab_plus_icon_size">14dp</dimen>
<dimen name="fab_plus_icon_stroke">2dp</dimen>
<dimen name="fab_shadow_offset">3dp</dimen>
<dimen name="fab_shadow_radius">9dp</dimen>
<dimen name="fab_stroke_width">1dp</dimen>
<dimen name="fab_actions_spacing">16dp</dimen>
<dimen name="fab_labels_margin">8dp</dimen>
</resources>
================================================
FILE: app/src/main/res/values/ids.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="tag_loader"/>
<item type="id" name="tag_nodata"/>
<item type="id" name="tag_holder"/>
<item type="id" name="tag_other"/>
<item type="id" name="fab_expand_menu_button"/>
<item type="id" name="fab_label"/>
<item type="id" name="ex_tag_holder"/>
</resources>
================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">WhiteBoard</string>
<!--白板-->
<string name="white_board_name">白板工具</string>
<string name="white_board_export">导出</string>
<string name="white_board_save">保存</string>
<string name="white_board_pen">画笔设置</string>
<string name="white_board_text">文本设置</string>
<string name="white_board_text_hint">双击修改</string>
<string name="white_board_eraser">橡皮擦</string>
<string name="white_board_eraser_clear">全部清除</string>
<string name="white_board_export_tip">导出成功,该页已保存图片至</string>
<string name="white_board_export_fail">导出失败,请稍后重试!</string>
<string name="white_board_save_sucess">保存成功!</string>
<string name="app_logout">继续按返回键退出</string>
<string name="app_list">本地资源</string>
<string name="app_list_loading">载入中...</string>
</resources>
================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="HeaderTextView">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">match_parent</item>
<item name="android:gravity">center</item>
<item name="android:textSize">@dimen/font_40px</item>
<item name="android:textColor">@color/white</item>
</style>
<style name="menu_labels_style">
<item name="android:background">@drawable/fab_label_background</item>
<item name="android:textColor">@color/white</item>
</style>
</resources>
================================================
FILE: app/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
================================================
FILE: build.gradle
================================================
buildscript {
repositories {
maven { url 'http://maven.oschina.net/content/groups/public/' }
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0'
}
}
allprojects {
repositories {
maven { url 'http://maven.oschina.net/content/groups/public/' }
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
================================================
FILE: settings.gradle
================================================
include ':app', ':wblib'
================================================
FILE: wblib/.gitignore
================================================
/build
================================================
FILE: wblib/build.gradle
================================================
apply plugin: 'com.android.library'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.github.guanpy:eventbus:1.0.0'
}
================================================
FILE: wblib/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\software\Java\Android\sdk_studio/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: wblib/src/androidTest/java/com/github/guanpy/wblib/ApplicationTest.java
================================================
package com.github.guanpy.wblib;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}
================================================
FILE: wblib/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.guanpy.wblib">
<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true">
</application>
</manifest>
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/DrawPenPoint.java
================================================
package com.github.guanpy.wblib.bean;
import android.graphics.Paint;
import android.graphics.Path;
/**
* 绘画存储-画笔路径
* Created 2015-7-13 10:36:1
*
* @author gpy
*/
public class DrawPenPoint {
/**
* 绘画路径
*/
private Path mPath;
/**
* 画笔
*/
private Paint mPaint;
/**
* 获得绘画路径
* Created 2015-7-13 10:36:1
*
* @return 绘画路径
* @author gpy
*/
public Path getPath() {
return mPath;
}
/**
* 设置绘画路径
* Created 2015-7-13 10:36:1
*
* @param path 绘画路径
* @author gpy
*/
public void setPath(Path path) {
this.mPath = path;
}
/**
* 获得画笔
* Created 2015-7-13 10:36:1
*
* @return 画笔
* @author gpy
*/
public Paint getPaint() {
return mPaint;
}
/**
* 设置画笔
* Created 2015-7-13 10:36:1
*
* @param paint 画笔
* @author gpy
*/
public void setPaint(Paint paint) {
this.mPaint = paint;
}
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/DrawPenStr.java
================================================
package com.github.guanpy.wblib.bean;
import java.util.ArrayList;
import java.util.List;
/**
* 绘画存储-画笔路径(字符串格式,方便储存)
* Created 2015-7-13 10:36:1
*
* @author gpy
*/
public class DrawPenStr {
/**画笔颜色*/
private int mColor;
/**画笔粗细*/
private float mStrokeWidth;
/**是否橡皮擦*/
private boolean mIsEraser;
/**移动到初始点坐标*/
private Point mMoveTo;
/**移动中A集*/
private List<Point> mQuadToA;
/**移动中B集*/
private List<Point> mQuadToB;
/**移动到终点坐标*/
private Point mLineTo;
/**所在界面高距坐标*/
private Point mOffset;
/**
*获得画笔颜色
*Created 2015-7-21 18:11:48
*@return 画笔颜色
*@author gpy
*/
public int getColor() {
return mColor;
}
/**
*设置画笔颜色
*Created 2015-7-21 18:11:48
*@param color 画笔颜色
*@author gpy
*/
public void setColor(int color) {
this.mColor = color;
}
/**
*获得画笔粗细
*Created 2015-7-21 18:11:48
*@return 画笔粗细
*@author gpy
*/
public float getStrokeWidth() {
return mStrokeWidth;
}
/**
*设置画笔粗细
*Created 2015-7-21 18:11:48
*@param strokeWidth 画笔粗细
*@author gpy
*/
public void setStrokeWidth(float strokeWidth) {
this.mStrokeWidth = strokeWidth;
}
/**
*获得是否橡皮擦
*Created 2015-7-21 18:11:48
*@return 是否橡皮擦
*@author gpy
*/
public boolean getIsEraser() {
return mIsEraser;
}
/**
*设置是否橡皮擦
*Created 2015-7-21 18:11:48
*@param isEraser 是否橡皮擦
*@author gpy
*/
public void setIsEraser(boolean isEraser) {
this.mIsEraser = isEraser;
}
/**
*获得移动到初始点坐标
*Created 2015-7-21 18:11:48
*@return 移动到初始点坐标
*@author gpy
*/
public Point getMoveTo() {
return mMoveTo;
}
/**
*设置移动到初始点坐标
*Created 2015-7-21 18:11:48
*@param moveTo 移动到初始点坐标
*@author gpy
*/
public void setMoveTo(Point moveTo) {
this.mMoveTo = moveTo;
}
/**
*获得移动中A集
*Created 2015-7-21 18:11:48
*@return 移动中A集
*@author gpy
*/
public List<Point> getQuadToA() {
if(null==mQuadToA){
mQuadToA = new ArrayList<Point>();
}
return mQuadToA;
}
/**
*设置移动中A集
*Created 2015-7-21 18:11:48
*@param quadToA 移动中A集
*@author gpy
*/
public void setQuadToA(List<Point> quadToA) {
this.mQuadToA = quadToA;
}
/**
*获得移动中B集
*Created 2015-7-21 18:11:48
*@return 移动中B集
*@author gpy
*/
public List<Point> getQuadToB() {
if(null==mQuadToB){
mQuadToB = new ArrayList<Point>();
}
return mQuadToB;
}
/**
*设置移动中B集
*Created 2015-7-21 18:11:48
*@param quadToB 移动中B集
*@author gpy
*/
public void setQuadToB(List<Point> quadToB) {
this.mQuadToB = quadToB;
}
/**
*获得移动到终点坐标
*Created 2015-7-21 18:11:48
*@return 移动到终点坐标
*@author gpy
*/
public Point getLineTo() {
return mLineTo;
}
/**
*设置移动到终点坐标
*Created 2015-7-21 18:11:48
*@param lineTo 移动到终点坐标
*@author gpy
*/
public void setLineTo(Point lineTo) {
this.mLineTo = lineTo;
}
/**
*获得所在界面高距坐标
*Created 2015-7-21 18:11:48
*@return 所在界面高距坐标
*@author gpy
*/
public Point getOffset() {
return mOffset;
}
/**
*设置所在界面高距坐标
*Created 2015-7-21 18:11:48
*@param offset 所在界面高距坐标
*@author gpy
*/
public void setOffset(Point offset) {
this.mOffset = offset;
}
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/DrawPoint.java
================================================
package com.github.guanpy.wblib.bean;
import com.github.guanpy.wblib.utils.BeanUtil;
public class DrawPoint {
/**绘画类型*/
private int mType;
/**画笔路径*/
private DrawPenPoint mDrawPen;
/**文字*/
private DrawTextPoint mDrawText;
/**画笔路径(字符形式)*/
private DrawPenStr mDrawPenStr;
/**
*获得画笔路径(字符形式)
*Created 2015-7-21 17:9:7
*@return 画笔路径(字符形式)
*@author gpy
*/
public DrawPenStr getDrawPenStr() {
return mDrawPenStr;
}
/**
*设置画笔路径(字符形式)
*Created 2015-7-21 17:9:7
*@param DrawPenStr 画笔路径(字符形式)
*@author gpy
*/
public void setDrawPenStr(DrawPenStr DrawPenStr) {
this.mDrawPenStr = DrawPenStr;
}
/**
*获得绘画类型
*Created 2015-7-13 10:42:14
*@return 绘画类型
*@author gpy
*/
public int getType() {
return mType;
}
/**
*设置绘画类型
*Created 2015-7-13 10:42:14
*@param type 绘画类型
*@author gpy
*/
public void setType(int type) {
this.mType = type;
}
/**
*获得画笔路径
*Created 2015-7-13 10:42:14
*@return 画笔路径
*@author gpy
*/
public DrawPenPoint getDrawPen() {
return mDrawPen;
}
/**
*设置画笔路径
*Created 2015-7-13 10:42:14
*@param drawPen 画笔路径
*@author gpy
*/
public void setDrawPen(DrawPenPoint drawPen) {
this.mDrawPen = drawPen;
}
/**
*获得文字
*Created 2015-7-13 10:42:14
*@return 文字
*@author gpy
*/
public DrawTextPoint getDrawText() {
return mDrawText;
// if(null==mDrawTexts||mDrawTexts.size()==0){
// return null;
// }
// return mDrawTexts.get(0);
}
/**
*设置文字
*Created 2015-7-13 10:42:14
*@param drawText 文字
*@author gpy
*/
public void setDrawText(DrawTextPoint drawText) {
mDrawText = drawText;
// if(null==drawText){
// return;
// }
// if(null==mDrawTexts){
// mDrawTexts = new ArrayList<DrawTextPoint>();
// }
// mDrawTexts.add(0,drawText);
}
/**
* 拷贝数据,防止引用传递 <br>
* 只在文字情况下使用
* Created 2015-8-10 16:55:49
*
* @author : gpy
*/
public static DrawPoint copyDrawPoint(DrawPoint drawPoint) {
DrawPoint dp = new DrawPoint();
try {
dp.setType(drawPoint.getType());
DrawTextPoint dtp = new DrawTextPoint();
dtp = (DrawTextPoint) BeanUtil.CopyBeanToBean(drawPoint.getDrawText(), dtp);
dp.setDrawText(dtp);
} catch (Exception e) {
e.printStackTrace();
}
return dp;
}
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/DrawTextPoint.java
================================================
package com.github.guanpy.wblib.bean;
/**
* 绘画存储-文字
* Created 2015-7-13 10:36:1
*
* @author gpy
*/
public class DrawTextPoint {
/**
* 唯一性标识
*/
private long mId;
/**
* 文字x坐标
*/
private float mX;
/**
* 文字y坐标
*/
private float mY;
/**
* 文字
*/
private String mStr;
/**
* 是否有下划线
*/
private boolean mIsUnderline;
/**
* 是否斜体
*/
private boolean mIsItalics;
/**
* 是否粗体
*/
private boolean mIsBold;
/**
* 文字颜色
*/
private int mColor;
/**
* 当前文字状态
*/
private int mStatus;
/**
* 是否显示
*/
private boolean mIsVisible;
/**
* 获得唯一性标识
* Created 2015-7-13 10:42:14
*
* @return 唯一性标识
* @author gpy
*/
public long getId() {
return mId;
}
/**
* 设置唯一性标识
* Created 2015-7-13 10:42:14
*
* @param id 唯一性标识
* @author gpy
*/
public void setId(long id) {
this.mId = id;
}
/**
* 获得文字x坐标
* Created 2015-7-13 10:34:39
*
* @return 文字x坐标
* @author gpy
*/
public float getX() {
return mX;
}
/**
* 设置文字x坐标
* Created 2015-7-13 10:34:39
*
* @param x 文字x坐标
* @author gpy
*/
public void setX(float x) {
this.mX = x;
}
/**
* 获得文字y坐标
* Created 2015-7-13 10:34:39
*
* @return 文字y坐标
* @author gpy
*/
public float getY() {
return mY;
}
/**
* 设置文字y坐标
* Created 2015-7-13 10:34:39
*
* @param y 文字y坐标
* @author gpy
*/
public void setY(float y) {
this.mY = y;
}
/**
* 获得文字
* Created 2015-7-13 10:34:39
*
* @return 文字
* @author gpy
*/
public String getStr() {
return mStr;
}
/**
* 设置文字
* Created 2015-7-13 10:34:39
*
* @param str 文字
* @author gpy
*/
public void setStr(String str) {
this.mStr = str;
}
/**
* 获得是否有下划线
* Created 2015-7-17 14:57:13
*
* @return 是否有下划线
* @author gpy
*/
public boolean getIsUnderline() {
return mIsUnderline;
}
/**
* 设置是否有下划线
* Created 2015-7-17 14:57:13
*
* @param isUnderline 是否有下划线
* @author gpy
*/
public void setIsUnderline(boolean isUnderline) {
this.mIsUnderline = isUnderline;
}
/**
* 获得是否斜体
* Created 2015-7-17 14:57:13
*
* @return 是否斜体
* @author gpy
*/
public boolean getIsItalics() {
return mIsItalics;
}
/**
* 设置是否斜体
* Created 2015-7-17 14:57:13
*
* @param isItalics 是否斜体
* @author gpy
*/
public void setIsItalics(boolean isItalics) {
this.mIsItalics = isItalics;
}
/**
* 获得是否粗体
* Created 2015-7-17 14:57:13
*
* @return 是否粗体
* @author gpy
*/
public boolean getIsBold() {
return mIsBold;
}
/**
* 设置是否粗体
* Created 2015-7-17 14:57:13
*
* @param isBold 是否粗体
* @author gpy
*/
public void setIsBold(boolean isBold) {
this.mIsBold = isBold;
}
/**
* 获得文字颜色
* Created 2015-7-17 15:40:0
*
* @return 文字颜色
* @author gpy
*/
public int getColor() {
return mColor;
}
/**
* 设置文字颜色
* Created 2015-7-17 15:40:0
*
* @param color 文字颜色
* @author gpy
*/
public void setColor(int color) {
this.mColor = color;
}
/**
* 获得当前文字状态
* Created 2015-7-13 10:34:39
*
* @return 当前文字状态
* @author gpy
*/
public int getStatus() {
return mStatus;
}
/**
* 设置当前文字状态
* Created 2015-7-13 10:34:39
*
* @param status 当前文字状态
* @author gpy
*/
public void setStatus(int status) {
this.mStatus = status;
}
/**
* 获得是否显示
* Created 2015-7-13 11:31:52
*
* @return 是否显示
* @author gpy
*/
public boolean getIsVisible() {
return mIsVisible;
}
/**
* 设置是否显示
* Created 2015-7-13 11:31:52
*
* @param isVisible 是否显示
* @author gpy
*/
public void setIsVisible(boolean isVisible) {
this.mIsVisible = isVisible;
}
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/Point.java
================================================
package com.github.guanpy.wblib.bean;
/**
* Created by gpy on 2015/8/21.
*/
public class Point {
/**
* X坐标
*/
private float mX;
/**
* Y坐标
*/
private float mY;
public Point(){
}
public Point(float x,float y){
mX = x;
mY = y;
}
/**
* 获得X坐标
* Created 2015-7-21 18:6:32
*
* @return X坐标
* @author gpy
*/
public float getX() {
return mX;
}
/**
* 设置X坐标
* Created 2015-7-21 18:6:32
*
* @param x X坐标
* @author gpy
*/
public void setX(float x) {
this.mX = x;
}
/**
* 获得Y坐标
* Created 2015-7-21 18:6:32
*
* @return Y坐标
* @author gpy
*/
public float getY() {
return mY;
}
/**
* 设置Y坐标
* Created 2015-7-21 18:6:32
*
* @param y Y坐标
* @author gpy
*/
public void setY(float y) {
this.mY = y;
}
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/WhiteBoardPoint.java
================================================
package com.github.guanpy.wblib.bean;
import java.util.ArrayList;
import java.util.List;
/**
* 画板绘画路径存储
*
* @author gpy
*/
public class WhiteBoardPoint {
/**
* 画板id
*/
private int mId;
/**
* 保存路径
*/
private List<DrawPoint> mSavePoints;
/**
* 撤销路径
*/
private List<DrawPoint> mDeletePoints;
/**
* 获得画板id Created 2015-7-12 10:6:10
*
* @return 画板id
* @author gpy
*/
public int getId() {
return mId;
}
/**
* 设置画板id Created 2015-7-12 10:6:10
*
* @param id 画板id
* @author gpy
*/
public void setId(int id) {
this.mId = id;
}
/**
* 获得保存路径 Created 2015-7-12 10:6:10
*
* @return 保存路径
* @author gpy
*/
public List<DrawPoint> getSavePoints() {
if (mSavePoints == null) {
mSavePoints = new ArrayList<DrawPoint>();
}
return mSavePoints;
}
/**
* 获得撤销路径 Created 2015-7-12 10:6:10
*
* @return 撤销路径
* @author gpy
*/
public List<DrawPoint> getDeletePoints() {
if (mDeletePoints == null) {
mDeletePoints = new ArrayList<DrawPoint>();
}
return mDeletePoints;
}
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/WhiteBoardPoints.java
================================================
package com.github.guanpy.wblib.bean;
import java.util.List;
/**
* 画板合集
* Created by gpy on 2015/8/21.
*/
public class WhiteBoardPoints {
/**唯一性id*/
private String mId;
/**画板合集*/
private List<WhiteBoardPoint> mWhiteBoardPoints;
/**
*获得唯一性id
*Created 2015-7-21 15:19:17
*@return 唯一性id
*@author gpy
*/
public String getId() {
return mId;
}
/**
*设置唯一性id
*Created 2015-7-21 15:19:17
*@param id 唯一性id
*@author gpy
*/
public void setId(String id) {
this.mId = id;
}
/**
*获得画板合集
*Created 2015-7-21 15:19:17
*@return 画板合集
*@author gpy
*/
public List<WhiteBoardPoint> getWhiteBoardPoints() {
return mWhiteBoardPoints;
}
/**
*设置画板合集
*Created 2015-7-21 15:19:17
*@param whiteBoardPoints 画板合集
*@author gpy
*/
public void setWhiteBoardPoints(List<WhiteBoardPoint> whiteBoardPoints) {
this.mWhiteBoardPoints = whiteBoardPoints;
}
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/utils/AppContextUtil.java
================================================
package com.github.guanpy.wblib.utils;
import android.content.Context;
/**
* AppContextUtil
*
* @author yangz
* @version 2014/11/4
*/
public class AppContextUtil {
private static Context sContext;
public static void init(Context ctx) {
sContext = ctx.getApplicationContext();
}
public static Context getContext() {
return sContext;
}
public static int getColor(int resId) {
if (sContext == null) {
return -1;
}
return sContext.getResources().getColor(resId);
}
public static String getString(int resId) {
if (sContext == null) {
return null;
}
return sContext.getResources().getString(resId);
}
public static String getString(int resId, Object... objs) {
if (sContext == null) {
return null;
}
return sContext.getResources().getString(resId, objs);
}
/**
* dip转px
*/
public static int dip2px(float dpValue) {
final float scale = AppContextUtil.getContext().getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/utils/BeanUtil.java
================================================
package com.github.guanpy.wblib.utils;
import java.lang.reflect.Method;
/**
* Created by gpy on 2015/8/13.
*/
public class BeanUtil {
/**
* @return Object
* <p/>
* 用到反射机制
* <p/>
* 此方法将调用obj1的getter方法,将得到的值作为相应的参数传给obj2的setter方法
* <p/>
* 注意,obj1的getter方法和obj2方法必须是public类型
* @parameter Object obj1,Object obj2
*/
public static Object CopyBeanToBean(Object obj1, Object obj2) throws Exception {
Method[] method1 = obj1.getClass().getMethods();
Method[] method2 = obj2.getClass().getMethods();
String methodName1;
String methodFix1;
String methodName2;
String methodFix2;
for (int i = 0; i < method1.length; i++) {
methodName1 = method1[i].getName();
methodFix1 = methodName1.substring(3, methodName1.length());
if (methodName1.startsWith("get")) {
for (int j = 0; j < method2.length; j++) {
methodName2 = method2[j].getName();
methodFix2 = methodName2.substring(3, methodName2.length());
if (methodName2.startsWith("set")) {
if (methodFix2.equals(methodFix1)) {
Object[] objs1 = new Object[0];
Object[] objs2 = new Object[1];
objs2[0] = method1[i].invoke(obj1, objs1);//激活obj1的相应的get的方法,objs1数组存放调用该方法的参数,此例中没有参数,该数组的长度为0
method2[j].invoke(obj2, objs2);//激活obj2的相应的set的方法,objs2数组存放调用该方法的参数
continue;
}
}
}
}
}
return obj2;
}
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/utils/Events.java
================================================
package com.github.guanpy.wblib.utils;
/**
* @author gpy
* @version 2015/8/26.
*/
public class Events {
/**
* 白板相关
*/
public static final String WHITE_BOARD_UNDO_REDO = "undo_redo";
public static final String WHITE_BOARD_TEXT_EDIT = "text_edit";
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/utils/OperationUtils.java
================================================
package com.github.guanpy.wblib.utils;
import com.github.guanpy.wblib.bean.DrawPoint;
import com.github.guanpy.wblib.bean.WhiteBoardPoint;
import com.github.guanpy.wblib.bean.WhiteBoardPoints;
import java.util.ArrayList;
import java.util.List;
/**
* 白板操作公共类
*
* @author gpy
*/
public class OperationUtils {
/**
* 操作类型-画笔
*/
public static final int DRAW_PEN = 1;
/**
* 操作类型-文字
*/
public static final int DRAW_TEXT = 2;
/**
* 操作类型-橡皮擦
*/
public static final int DRAW_ERASER = 3;
/**
* 单例
*/
private static OperationUtils mOperationStack;
/**
* 当前是否禁止白板操作
*/
public boolean DISABLE = true;
/**
* 当前所在白板位置
*/
public int mCurrentIndex = 0;
/**
* 每次操作的唯一标识
*/
private long markId = 0;
/**
* 当前按钮点击
*/
public int mCurrentOPerationPen = WhiteBoardVariable.Operation.PEN_CLICK;
/**
* 当前按钮点击
*/
public int mCurrentOPerationColor = WhiteBoardVariable.Operation.COLOR_NORMAL;
/**
* 当前按钮点击
*/
public int mCurrentOPerationText = WhiteBoardVariable.Operation.TEXT_NORMAL;
/**
* 当前按钮点击
*/
public int mCurrentOPerationEraser = WhiteBoardVariable.Operation.ERASER_NORMAL;
/**
* 当前绘画类型:笔或者文字等
*/
public int mCurrentDrawType = DRAW_PEN;
/**
* 当前颜色
*/
public int mCurrentColor = WhiteBoardVariable.Color.ORANGE;
/**
* 当前画笔大小
*/
public int mCurrentPenSize = WhiteBoardVariable.PenSize.MIDDLE;
/**
* 当前橡皮擦大小
*/
public int mCurrentEraserSize = WhiteBoardVariable.EraserSize.MIDDLE;
/**
* 白板操作集
*/
private WhiteBoardPoints mWhiteBoardPoints;
/**
* 单例
*/
public static OperationUtils getInstance() {
if (mOperationStack == null) {
mOperationStack = new OperationUtils();
}
return mOperationStack;
}
/**
* 私有实例化
*/
private OperationUtils() {
}
/**
* 初始化操作集
*/
public void init() {
DISABLE = true;
mCurrentIndex = 0;
markId = 0;
mCurrentOPerationPen = WhiteBoardVariable.Operation.PEN_NORMAL;
mCurrentOPerationColor = WhiteBoardVariable.Operation.COLOR_NORMAL;
mCurrentOPerationText = WhiteBoardVariable.Operation.TEXT_NORMAL;
mCurrentOPerationEraser = WhiteBoardVariable.Operation.ERASER_NORMAL;
mCurrentDrawType = DRAW_PEN;
mCurrentColor = WhiteBoardVariable.Color.ORANGE;
mCurrentPenSize = WhiteBoardVariable.PenSize.MIDDLE;
mCurrentEraserSize = WhiteBoardVariable.EraserSize.MIDDLE;
OperationUtils.getInstance().initDrawPointList();
}
/**
* 返回指定白板的操作集
*/
public WhiteBoardPoint getDrawPointList(int i) {
if (null != mWhiteBoardPoints) {
if (mWhiteBoardPoints.getWhiteBoardPoints().size() <= i) {
WhiteBoardPoint drawPointList = new WhiteBoardPoint();
drawPointList.setId(i);
mWhiteBoardPoints.getWhiteBoardPoints().add(drawPointList);
return getDrawPointList(i);
} else {
return mWhiteBoardPoints.getWhiteBoardPoints().get(i);
}
} else {
mWhiteBoardPoints = new WhiteBoardPoints();
mWhiteBoardPoints.setWhiteBoardPoints(new ArrayList<WhiteBoardPoint>());
return getDrawPointList(i);
}
}
/**
* 返回指定白板的操作集大小
*/
public int getDrawPointSize() {
if (mWhiteBoardPoints != null && null != mWhiteBoardPoints.getWhiteBoardPoints()) {
return mWhiteBoardPoints.getWhiteBoardPoints().size();
} else {
getDrawPointList(mCurrentIndex);
return getDrawPointSize();
}
}
/**
* 返回指定白板的操作集
*/
public WhiteBoardPoints getWhiteBoardPoints() {
return mWhiteBoardPoints;
}
/**
* 返回指定白板的操作集
*/
public void setWhiteBoardPoints(WhiteBoardPoints whiteBoardPoints) {
mWhiteBoardPoints = whiteBoardPoints;
}
/**
* 初始化白板
*/
public void initDrawPointList() {
if (mWhiteBoardPoints != null && mWhiteBoardPoints.getWhiteBoardPoints() != null) {
mWhiteBoardPoints.getWhiteBoardPoints().clear();
} else {
getDrawPointList(mCurrentIndex);
}
}
/**
* 新建白板
*/
public void newPage() {
mCurrentIndex = getDrawPointSize();
getDrawPointList(mCurrentIndex);
}
/**
* 获取每次操作的唯一标识
*/
public long getNewMarkId() {
return markId++;
}
/**
* 获取当前白板操作集
*/
public List<DrawPoint> getSavePoints() {
return OperationUtils.getInstance().getDrawPointList(OperationUtils.getInstance().mCurrentIndex).getSavePoints();
}
/**
* 获取当前白板删除操作集
*/
public List<DrawPoint> getDeletePoints() {
return OperationUtils.getInstance().getDrawPointList(OperationUtils.getInstance().mCurrentIndex).getDeletePoints();
}
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/utils/WhiteBoardVariable.java
================================================
package com.github.guanpy.wblib.utils;
import com.github.guanpy.wblib.R;
/**
* 白板属性值汇总
* Created by gpy on 2015/8/17.
*/
public final class WhiteBoardVariable {
/**白板工具栏操作*/
public interface Operation{
/**画笔-正常*/
int PEN_NORMAL = 1 ;
/**画笔-点击*/
int PEN_CLICK = 2 ;
/**画笔-展开*/
int PEN_EXPAND = 3 ;
/**颜色-正常*/
int COLOR_NORMAL = 4 ;
/**颜色-点击*/
int COLOR_CLICK = 5 ;
/**颜色-展开*/
int COLOR_EXPAND = 6 ;
/**文字-正常*/
int TEXT_NORMAL = 7 ;
/**文字-点击*/
int TEXT_CLICK = 8 ;
/**文字-展开*/
int TEXT_EXPAND =9 ;
/**橡皮擦-正常*/
int ERASER_NORMAL = 10 ;
/**橡皮擦-点击*/
int ERASER_CLICK = 11 ;
/**橡皮擦-展开*/
int ERASER_EXPAND = 12 ;
/**点击外围*/
int OUTSIDE_CLICK = 13 ;
}
/**颜色*/
public interface Color{
/**黑色*/
int BLACK = AppContextUtil.getContext().getResources().getColor(R.color.grey_3e);
/**橙色*/
int ORANGE = AppContextUtil.getContext().getResources().getColor(R.color.orange);
/**粉色*/
int PINK = AppContextUtil.getContext().getResources().getColor(R.color.light_red);
/**紫色*/
int PURPLE = AppContextUtil.getContext().getResources().getColor(R.color.primary_purple);
/**绿色*/
int GREEN = AppContextUtil.getContext().getResources().getColor(R.color.green);
}
/**画笔大小*/
public interface PenSize{
/**大*/
int LARRGE = AppContextUtil.dip2px(9);
/**中*/
int MIDDLE = AppContextUtil.dip2px(6);
/**小*/
int MINI = AppContextUtil.dip2px(4);
}
/**橡皮擦大小*/
public interface EraserSize{
/**大*/
int LARRGE = AppContextUtil.dip2px(16);
/**中*/
int MIDDLE = AppContextUtil.dip2px(9);
/**小*/
int MINI = AppContextUtil.dip2px(4);
}
/**圆环宽度大小*/
public interface RingSize{
/**大*/
int LARRGE = AppContextUtil.dip2px(3);
/**小*/
int MINI = AppContextUtil.dip2px(1);
}
/**文字风格*/
public interface TextStyle{
/**设置下划线*/
int CHANGE_UNDERLINE = 1;
/**设置斜体*/
int CHANGE_ITALICS =2;
/**设置粗体*/
int CHANGE_BOLD = 3;
}
}
================================================
FILE: wblib/src/main/java/com/github/guanpy/wblib/widget/DrawPenView.java
================================================
package com.github.guanpy.wblib.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.github.guanpy.library.EventBus;
import com.github.guanpy.wblib.R;
import com.github.guanpy.wblib.bean.DrawPenPoint;
import com.github.guanpy.wblib.bean.DrawPenStr;
import com.github.guanpy.wblib.bean.DrawPoint;
import com.github.guanpy.wblib.bean.Point;
import com.github.guanpy.wblib.utils.Events;
import com.github.guanpy.wblib.utils.OperationUtils;
import java.util.Iterator;
public class DrawPenView extends View {
/**
* 用于画线
*/
private Paint mPaint = null;
/**
* 用于画图
*/
private Paint mBitmapPaint = null;
/**
* 画图路径
*/
private Path mPath = null;
/**
* 步骤存储bean
*/
private DrawPoint mDrawPath = null;
/**
* 绘画存储-画笔路径(字符串格式,方便储存)
*/
private DrawPenStr mDrawPenStr = null;
/**
* 画图
*/
private Bitmap mBottomBitmap = null;
private int mBottomBitmapDrawHeight = 0;
float posX, posY;
private final float TOUCH_TOLERANCE = 4;
private Context mContext;
private Canvas mCanvas = null;
public DrawPenView(Context context, AttributeSet attr, int defStyle) {
super(context, attr, defStyle);
initView(context);
}
public DrawPenView(Context context, AttributeSet attr) {
super(context, attr);
initView(context);
}
public DrawPenView(Context context) {
super(context);
initView(context);
}
private void initView(Context context) {
mContext = context;
initPaint();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
public void init(Paint paint) {
if (paint == null) {
initPaint();
} else {
mPaint = paint;
}
}
/**
* 初始化画笔
*/
private void initPaint() {
mPaint = new Paint();
mPaint.setAntiAlias(true);//是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢
mPaint.setDither(true);// 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
mPaint.setColor(OperationUtils.getInstance().mCurrentColor);//设置绘制的颜色
mPaint.setStyle(Paint.Style.STROKE);//设置画笔的样式
mPaint.setStrokeJoin(Paint.Join.ROUND);//设置绘制时各图形的结合方式,如平滑效果等
mPaint.setStrokeCap(Paint.Cap.ROUND);//当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,如圆形样式 Cap.ROUND,或方形样式Cap.SQUARE
mPaint.setStrokeWidth(2 * OperationUtils.getInstance().mCurrentPenSize);//当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度
}
/**
* 初始化画笔
*/
public void changeEraser() {
mPaint.setColor(mContext.getResources().getColor(R.color.transparent));
mPaint.setStrokeWidth(2 * OperationUtils.getInstance().mCurrentEraserSize);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));//擦除模式
postInvalidate();
}
/**
* 修改橡皮擦尺寸
*/
public void setEraserSize() {
mPaint.setStrokeWidth(2 * OperationUtils.getInstance().mCurrentEraserSize);//size为圆半径
postInvalidate();
}
/**
* 修改画笔尺寸
*/
public void setPenSize() {
mPaint.setStrokeWidth(2 * OperationUtils.getInstance().mCurrentPenSize);//size为圆半径
postInvalidate();
}
/**
* 修改画笔颜色
*/
public void setPenColor() {
mPaint.setColor(OperationUtils.getInstance().mCurrentColor);
postInvalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if(w>0&&h>0){
mBottomBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBottomBitmap);
}
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawColor(mContext.getResources().getColor(R.color.transparent));
int nCanvasHeight = canvas.getHeight();
int nBitmapHeight = mBottomBitmap.getHeight();
mBottomBitmapDrawHeight = (nCanvasHeight - nBitmapHeight) / 2;
canvas.drawBitmap(mBottomBitmap, 0, mBottomBitmapDrawHeight, mBitmapPaint);
if (mPath != null) {
canvas.drawPath(mPath, mPaint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (OperationUtils.getInstance().DISABLE && (OperationUtils.getInstance().mCurrentDrawType == OperationUtils.DRAW_PEN || OperationUtils.getInstance().mCurrentD
gitextract_yv6_nzdc/
├── .gitignore
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── example/
│ │ └── gpy/
│ │ └── whiteboard/
│ │ └── ApplicationTest.java
│ └── main/
│ ├── AndroidManifest.xml
│ ├── java/
│ │ └── com/
│ │ └── example/
│ │ └── gpy/
│ │ └── whiteboard/
│ │ ├── MainActivity.java
│ │ ├── SelfApplication.java
│ │ ├── bean/
│ │ │ └── WbInfo.java
│ │ ├── utils/
│ │ │ ├── FileUtil.java
│ │ │ ├── SdCardStatus.java
│ │ │ ├── StoreUtil.java
│ │ │ └── ToastUtils.java
│ │ └── view/
│ │ ├── WhiteBoardActivity.java
│ │ ├── base/
│ │ │ └── BaseActivity.java
│ │ └── widget/
│ │ └── floatingactionmenu/
│ │ ├── AddFloatingActionButton.java
│ │ ├── FloatingActionButton.java
│ │ ├── FloatingActionsMenu.java
│ │ ├── FloatingImageButton.java
│ │ └── TouchDelegateGroup.java
│ └── res/
│ ├── drawable/
│ │ ├── bg_white_board.xml
│ │ ├── common_cancel_selector.xml
│ │ ├── common_confirm_selector.xml
│ │ ├── draw_text_border.xml
│ │ ├── fab_label_background.xml
│ │ ├── ic_back_selector.xml
│ │ ├── white_board_add_selector.xml
│ │ ├── white_board_color_black_selector.xml
│ │ ├── white_board_color_green_selector.xml
│ │ ├── white_board_color_orange_selector.xml
│ │ ├── white_board_color_pink_selector.xml
│ │ ├── white_board_color_purple_selector.xml
│ │ ├── white_board_disable_selector.xml
│ │ ├── white_board_eraser_selected_selector.xml
│ │ ├── white_board_eraser_selector.xml
│ │ ├── white_board_export_selector.xml
│ │ ├── white_board_next_page_selector.xml
│ │ ├── white_board_pen_selected_selector.xml
│ │ ├── white_board_pen_selector.xml
│ │ ├── white_board_pre_page_selector.xml
│ │ ├── white_board_redo_selector.xml
│ │ ├── white_board_save_selector.xml
│ │ ├── white_board_text_bold_selected_selector.xml
│ │ ├── white_board_text_bold_selector.xml
│ │ ├── white_board_text_italics_selected_selector.xml
│ │ ├── white_board_text_italics_selector.xml
│ │ ├── white_board_text_selected_selector.xml
│ │ ├── white_board_text_selector.xml
│ │ ├── white_board_text_underline_selected_selector.xml
│ │ ├── white_board_text_underline_selector.xml
│ │ ├── white_board_undisable_selector.xml
│ │ └── white_board_undo_selector.xml
│ ├── layout/
│ │ ├── activity_main.xml
│ │ ├── activity_white_board.xml
│ │ ├── draw_text.xml
│ │ └── wb_item.xml
│ ├── values/
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── ids.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── values-w820dp/
│ └── dimens.xml
├── build.gradle
├── gradle.properties
├── settings.gradle
└── wblib/
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src/
├── androidTest/
│ └── java/
│ └── com/
│ └── github/
│ └── guanpy/
│ └── wblib/
│ └── ApplicationTest.java
└── main/
├── AndroidManifest.xml
├── java/
│ └── com/
│ └── github/
│ └── guanpy/
│ └── wblib/
│ ├── bean/
│ │ ├── DrawPenPoint.java
│ │ ├── DrawPenStr.java
│ │ ├── DrawPoint.java
│ │ ├── DrawTextPoint.java
│ │ ├── Point.java
│ │ ├── WhiteBoardPoint.java
│ │ └── WhiteBoardPoints.java
│ ├── utils/
│ │ ├── AppContextUtil.java
│ │ ├── BeanUtil.java
│ │ ├── Events.java
│ │ ├── OperationUtils.java
│ │ └── WhiteBoardVariable.java
│ └── widget/
│ ├── DrawPenView.java
│ ├── DrawTextLayout.java
│ └── DrawTextView.java
└── res/
├── drawable/
│ └── draw_text_border.xml
├── layout/
│ └── draw_text.xml
└── values/
├── colors.xml
└── strings.xml
SYMBOL INDEX (362 symbols across 31 files)
FILE: app/src/androidTest/java/com/example/gpy/whiteboard/ApplicationTest.java
class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
method ApplicationTest (line 10) | public ApplicationTest() {
FILE: app/src/main/java/com/example/gpy/whiteboard/MainActivity.java
class MainActivity (line 24) | public class MainActivity extends BaseActivity {
method getLayoutId (line 36) | @Override
method afterCreate (line 41) | @Override
method loadData (line 47) | private void loadData() {
method initView (line 65) | private void initView() {
method onBackPressed (line 77) | @Override
class WbAdapter (line 89) | private class WbAdapter extends BaseAdapter {
method getCount (line 90) | @Override
method getItem (line 95) | @Override
method getItemId (line 100) | @Override
method getView (line 105) | @Override
class WbViewHolder (line 132) | private final class WbViewHolder {
method WbViewHolder (line 135) | public WbViewHolder(final View view) {
FILE: app/src/main/java/com/example/gpy/whiteboard/SelfApplication.java
class SelfApplication (line 13) | public class SelfApplication extends Application{
method onCreate (line 15) | @Override
FILE: app/src/main/java/com/example/gpy/whiteboard/bean/WbInfo.java
class WbInfo (line 8) | public class WbInfo {
method getName (line 26) | public String getName() {
method setName (line 37) | public void setName(String name) {
method getFile (line 48) | public File getFile() {
method setFile (line 59) | public void setFile(File file) {
FILE: app/src/main/java/com/example/gpy/whiteboard/utils/FileUtil.java
class FileUtil (line 13) | public class FileUtil {
method getFileName (line 25) | public static String getFileName(File file) {
method getAutoFileOrFilesSize (line 42) | public static String getAutoFileOrFilesSize(String filePath) {
method getFileOrFilesSize (line 65) | public static double getFileOrFilesSize(String filePath, int sizeType) {
method getFileSize (line 88) | private static long getFileSize(File file) throws Exception {
method getFileSizes (line 108) | private static long getFileSizes(File f) throws Exception {
method FormetFileSize (line 127) | private static String FormetFileSize(long fileS) {
method FormetFileSize (line 153) | private static double FormetFileSize(long fileS, int sizeType) {
FILE: app/src/main/java/com/example/gpy/whiteboard/utils/SdCardStatus.java
class SdCardStatus (line 10) | public class SdCardStatus {
method init (line 14) | public static void init(String cacheFolderName) {
method getDefaulstCacheDirInSdCard (line 17) | public static String getDefaulstCacheDirInSdCard() throws IllegalState...
method getSDPath (line 31) | public static String getSDPath() {
FILE: app/src/main/java/com/example/gpy/whiteboard/utils/StoreUtil.java
class StoreUtil (line 33) | public class StoreUtil {
method getPhotoSavePath (line 45) | public static String getPhotoSavePath() {
method getPhotoPath (line 49) | public static String getPhotoPath() {
method getWbSavePath (line 55) | public static String getWbSavePath() {
method getWbPath (line 59) | public static String getWbPath() {
method saveWhiteBoardPoints (line 65) | public static void saveWhiteBoardPoints() {
method readWhiteBoardPoints (line 88) | public static void readWhiteBoardPoints(String filePath) {
method convertWhiteBoardPoints (line 101) | public static void convertWhiteBoardPoints(WhiteBoardPoints whiteBoard...
method write (line 141) | public static void write(String strWb, String path) {
method read (line 191) | public static String read(String wbPath) {
FILE: app/src/main/java/com/example/gpy/whiteboard/utils/ToastUtils.java
class ToastUtils (line 9) | public class ToastUtils {
method showToast (line 11) | public static void showToast(Context context, String string) {
method showToast (line 15) | public static void showToast(Context context, int intStr) {
FILE: app/src/main/java/com/example/gpy/whiteboard/view/WhiteBoardActivity.java
class WhiteBoardActivity (line 39) | public class WhiteBoardActivity extends BaseActivity implements View.OnC...
method afterCreate (line 128) | @Override
method initView (line 134) | private void initView() {
method initEvent (line 147) | private void initEvent() {
method onClick (line 210) | @Override
method setPenSize (line 324) | private void setPenSize(int size) {
method changePenBack (line 333) | private void changePenBack() {
method setColor (line 353) | private void setColor(int color) {
method changeColorBack (line 364) | private void changeColorBack() {
method setTextStyle (line 381) | private void setTextStyle(int textStyle) {
method changeTextBack (line 389) | private void changeTextBack() {
method setEraserSize (line 420) | private void setEraserSize(int size) {
method changeEraserBack (line 430) | private void changeEraserBack() {
method newPage (line 450) | private void newPage() {
method prePage (line 458) | private void prePage() {
method nextPage (line 468) | private void nextPage() {
method showPoints (line 478) | private void showPoints() {
method showPage (line 489) | private void showPage() {
method undo (line 506) | private void undo() {
method redo (line 527) | private void redo() {
method getLayoutId (line 545) | @Override
method afterEdit (line 553) | private void afterEdit(boolean isSave) {
method ToolsOperation (line 571) | private void ToolsOperation(int currentOperation) {
method showOutSideView (line 582) | private void showOutSideView() {
method setPenOperation (line 602) | private void setPenOperation(int currentOperation) {
method setColorOperation (line 662) | private void setColorOperation(int currentOperation) {
method setTextOperation (line 697) | private void setTextOperation(int currentOperation) {
method setEraserOperation (line 762) | private void setEraserOperation(int currentOperation) {
method saveImage (line 822) | public void saveImage() {
method onBackPressed (line 854) | @Override
method textEdit (line 860) | @ReceiveEvents(name = Events.WHITE_BOARD_TEXT_EDIT)
method showUndoRedo (line 875) | @ReceiveEvents(name = Events.WHITE_BOARD_UNDO_REDO)
FILE: app/src/main/java/com/example/gpy/whiteboard/view/base/BaseActivity.java
class BaseActivity (line 16) | public abstract class BaseActivity extends FragmentActivity {
method onCreate (line 18) | @Override
method getLayoutId (line 27) | protected abstract int getLayoutId();
method afterCreate (line 29) | protected abstract void afterCreate(Bundle savedInstanceState);
method showMessage (line 31) | protected void showMessage(CharSequence msg) {
method onResume (line 35) | @Override
method onPause (line 41) | @Override
method navi2Page (line 47) | public void navi2Page(final Class<?> page) {
method navi2Page (line 51) | public void navi2Page(final Class<?> page, final boolean shut) {
method navi2Page (line 55) | public void navi2Page(final Class<?> page, final Bundle data, final bo...
FILE: app/src/main/java/com/example/gpy/whiteboard/view/widget/floatingactionmenu/AddFloatingActionButton.java
class AddFloatingActionButton (line 18) | public class AddFloatingActionButton extends FloatingActionButton {
method AddFloatingActionButton (line 21) | public AddFloatingActionButton(Context context) {
method AddFloatingActionButton (line 25) | public AddFloatingActionButton(Context context, AttributeSet attrs) {
method AddFloatingActionButton (line 29) | public AddFloatingActionButton(Context context, AttributeSet attrs, in...
method init (line 33) | @Override
method getPlusColor (line 45) | public int getPlusColor() {
method setPlusColorResId (line 49) | public void setPlusColorResId(@ColorRes int plusColor) {
method setPlusColor (line 53) | public void setPlusColor(int color) {
method setIcon (line 60) | @Override
method getIconDrawable (line 65) | @Override
FILE: app/src/main/java/com/example/gpy/whiteboard/view/widget/floatingactionmenu/FloatingActionButton.java
class FloatingActionButton (line 37) | public class FloatingActionButton extends FloatingImageButton {
method FloatingActionButton (line 62) | public FloatingActionButton(Context context) {
method FloatingActionButton (line 66) | public FloatingActionButton(Context context, AttributeSet attrs) {
method FloatingActionButton (line 71) | public FloatingActionButton(Context context, AttributeSet attrs, int d...
method init (line 76) | void init(Context context, AttributeSet attributeSet) {
method updateDrawableSize (line 95) | private void updateDrawableSize() {
method updateCircleSize (line 99) | private void updateCircleSize() {
method setSize (line 103) | public void setSize(@FAB_SIZE int size) {
method getSize (line 116) | @FAB_SIZE
method setIcon (line 121) | public void setIcon(@DrawableRes int icon) {
method setIconDrawable (line 129) | public void setIconDrawable(@NonNull Drawable iconDrawable) {
method getColorNormal (line 140) | public int getColorNormal() {
method setColorNormalResId (line 144) | public void setColorNormalResId(@ColorRes int colorNormal) {
method setColorNormal (line 148) | public void setColorNormal(int color) {
method getColorPressed (line 158) | public int getColorPressed() {
method setColorPressedResId (line 162) | public void setColorPressedResId(@ColorRes int colorPressed) {
method setColorPressed (line 166) | public void setColorPressed(int color) {
method getColorDisabled (line 176) | public int getColorDisabled() {
method setColorDisabledResId (line 180) | public void setColorDisabledResId(@ColorRes int colorDisabled) {
method setColorDisabled (line 184) | public void setColorDisabled(int color) {
method setStrokeVisible (line 191) | public void setStrokeVisible(boolean visible) {
method isStrokeVisible (line 198) | public boolean isStrokeVisible() {
method getColor (line 202) | int getColor(@ColorRes int id) {
method getDimension (line 206) | float getDimension(@DimenRes int id) {
method setTitle (line 210) | public void setTitle(String title) {
method getLabelView (line 218) | TextView getLabelView() {
method getTitle (line 222) | public String getTitle() {
method onMeasure (line 226) | @Override
method updateBackground (line 232) | void updateBackground() {
method getIconDrawable (line 271) | Drawable getIconDrawable() {
method createFillDrawable (line 281) | private StateListDrawable createFillDrawable(float strokeWidth) {
method createCircleDrawable (line 289) | private Drawable createCircleDrawable(int color, float strokeWidth) {
class TranslucentLayerDrawable (line 314) | private static class TranslucentLayerDrawable extends LayerDrawable {
method TranslucentLayerDrawable (line 317) | public TranslucentLayerDrawable(int alpha, Drawable... layers) {
method draw (line 322) | @Override
method createOuterStrokeDrawable (line 331) | private Drawable createOuterStrokeDrawable(float strokeWidth) {
method opacityToAlpha (line 344) | private int opacityToAlpha(float opacity) {
method darkenColor (line 348) | private int darkenColor(int argb) {
method lightenColor (line 352) | private int lightenColor(int argb) {
method adjustColorBrightness (line 356) | private int adjustColorBrightness(int argb, float factor) {
method halfTransparent (line 365) | private int halfTransparent(int argb) {
method opaque (line 374) | private int opaque(int argb) {
method createInnerStrokesDrawable (line 382) | private Drawable createInnerStrokesDrawable(final int color, float str...
method setBackgroundCompat (line 412) | @SuppressWarnings("deprecation")
method setVisibility (line 422) | @Override
FILE: app/src/main/java/com/example/gpy/whiteboard/view/widget/floatingactionmenu/FloatingActionsMenu.java
class FloatingActionsMenu (line 29) | public class FloatingActionsMenu extends ViewGroup {
type OnFloatingActionsMenuUpdateListener (line 77) | public interface OnFloatingActionsMenuUpdateListener {
method onMenuExpanded (line 78) | void onMenuExpanded();
method onMenuCollapsed (line 80) | void onMenuCollapsed();
method FloatingActionsMenu (line 83) | public FloatingActionsMenu(Context context) {
method FloatingActionsMenu (line 87) | public FloatingActionsMenu(Context context, AttributeSet attrs) {
method FloatingActionsMenu (line 92) | public FloatingActionsMenu(Context context, AttributeSet attrs, int de...
type OnFloatingActionsMenuClickListener (line 96) | public interface OnFloatingActionsMenuClickListener{
method addButtonLister (line 98) | void addButtonLister();
method setOnFloatingActionsMenuClickListener (line 101) | public void setOnFloatingActionsMenuClickListener(OnFloatingActionsMe...
method drawRing (line 110) | public void drawRing(int color){
method clearDraw (line 116) | public void clearDraw(){
method setAddButtonBackground (line 123) | public void setAddButtonBackground(int drawable){
method dip2px (line 129) | private int dip2px(float dpValue) {
method init (line 133) | private void init(Context context, AttributeSet attributeSet) {
method setOnFloatingActionsMenuUpdateListener (line 165) | public void setOnFloatingActionsMenuUpdateListener(OnFloatingActionsMe...
method expandsHorizontally (line 169) | private boolean expandsHorizontally() {
class RotatingDrawable (line 173) | private static class RotatingDrawable extends LayerDrawable {
method RotatingDrawable (line 174) | public RotatingDrawable(Drawable drawable) {
method getRotation (line 180) | @SuppressWarnings("UnusedDeclaration")
method setRotation (line 185) | @SuppressWarnings("UnusedDeclaration")
method draw (line 191) | @Override
method createAddButton (line 203) | private void createAddButton(Context context) {
method getColor (line 261) | private int getColor(@ColorRes int id) {
method onMeasure (line 265) | @Override
method adjustForOvershoot (line 326) | private int adjustForOvershoot(int dimension) {
method onLayout (line 330) | @Override
method generateDefaultLayoutParams (line 460) | @Override
method generateLayoutParams (line 465) | @Override
method generateLayoutParams (line 470) | @Override
method checkLayoutParams (line 475) | @Override
class LayoutParams (line 484) | private class LayoutParams extends ViewGroup.LayoutParams {
method LayoutParams (line 492) | public LayoutParams(ViewGroup.LayoutParams source) {
method setAnimationsTarget (line 520) | public void setAnimationsTarget(View view) {
method onFinishInflate (line 537) | @Override
method collapse (line 547) | public void collapse() {
method toggle (line 560) | public void toggle() {
method expand (line 568) | public void expand() {
method isExpanded (line 581) | public boolean isExpanded() {
method onSaveInstanceState (line 585) | @Override
method onRestoreInstanceState (line 594) | @Override
class SavedState (line 611) | public static class SavedState extends BaseSavedState {
method SavedState (line 614) | public SavedState(Parcelable parcel) {
method SavedState (line 618) | private SavedState(Parcel in) {
method writeToParcel (line 623) | @Override
method createFromParcel (line 631) | @Override
method newArray (line 636) | @Override
FILE: app/src/main/java/com/example/gpy/whiteboard/view/widget/floatingactionmenu/FloatingImageButton.java
class FloatingImageButton (line 15) | public class FloatingImageButton extends ImageButton {
method FloatingImageButton (line 28) | public FloatingImageButton(Context context) {
method FloatingImageButton (line 32) | public FloatingImageButton(Context context, AttributeSet attrs) {
method FloatingImageButton (line 37) | public FloatingImageButton(Context context, AttributeSet attrs, int de...
method init (line 41) | private void init(Context context){
method drawMiniRing (line 49) | public void drawMiniRing(int color){
method drawLargeRing (line 56) | public void drawLargeRing(int color){
method drawRing (line 64) | public void drawRing(int size,int color){
method drawCircle (line 75) | public void drawCircle(int size){
method drawCircle (line 83) | public void drawCircle(int size,int color){
method drawCircleAndRing (line 95) | public void drawCircleAndRing(int size,int color){
method clearDraw (line 105) | public void clearDraw(){
method onDraw (line 109) | @Override
FILE: app/src/main/java/com/example/gpy/whiteboard/view/widget/floatingactionmenu/TouchDelegateGroup.java
class TouchDelegateGroup (line 11) | public class TouchDelegateGroup extends TouchDelegate {
method TouchDelegateGroup (line 17) | public TouchDelegateGroup(View uselessHackyView) {
method addTouchDelegate (line 21) | public void addTouchDelegate(@NonNull TouchDelegate touchDelegate) {
method removeTouchDelegate (line 25) | public void removeTouchDelegate(TouchDelegate touchDelegate) {
method clearTouchDelegates (line 32) | public void clearTouchDelegates() {
method onTouchEvent (line 37) | @Override
method setEnabled (line 68) | public void setEnabled(boolean enabled) {
FILE: wblib/src/androidTest/java/com/github/guanpy/wblib/ApplicationTest.java
class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
method ApplicationTest (line 10) | public ApplicationTest() {
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/DrawPenPoint.java
class DrawPenPoint (line 12) | public class DrawPenPoint {
method getPath (line 30) | public Path getPath() {
method setPath (line 41) | public void setPath(Path path) {
method getPaint (line 52) | public Paint getPaint() {
method setPaint (line 63) | public void setPaint(Paint paint) {
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/DrawPenStr.java
class DrawPenStr (line 12) | public class DrawPenStr {
method getColor (line 38) | public int getColor() {
method setColor (line 48) | public void setColor(int color) {
method getStrokeWidth (line 58) | public float getStrokeWidth() {
method setStrokeWidth (line 68) | public void setStrokeWidth(float strokeWidth) {
method getIsEraser (line 78) | public boolean getIsEraser() {
method setIsEraser (line 88) | public void setIsEraser(boolean isEraser) {
method getMoveTo (line 98) | public Point getMoveTo() {
method setMoveTo (line 108) | public void setMoveTo(Point moveTo) {
method getQuadToA (line 118) | public List<Point> getQuadToA() {
method setQuadToA (line 131) | public void setQuadToA(List<Point> quadToA) {
method getQuadToB (line 141) | public List<Point> getQuadToB() {
method setQuadToB (line 154) | public void setQuadToB(List<Point> quadToB) {
method getLineTo (line 164) | public Point getLineTo() {
method setLineTo (line 174) | public void setLineTo(Point lineTo) {
method getOffset (line 184) | public Point getOffset() {
method setOffset (line 194) | public void setOffset(Point offset) {
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/DrawPoint.java
class DrawPoint (line 6) | public class DrawPoint {
method getDrawPenStr (line 24) | public DrawPenStr getDrawPenStr() {
method setDrawPenStr (line 34) | public void setDrawPenStr(DrawPenStr DrawPenStr) {
method getType (line 45) | public int getType() {
method setType (line 55) | public void setType(int type) {
method getDrawPen (line 67) | public DrawPenPoint getDrawPen() {
method setDrawPen (line 77) | public void setDrawPen(DrawPenPoint drawPen) {
method getDrawText (line 87) | public DrawTextPoint getDrawText() {
method setDrawText (line 102) | public void setDrawText(DrawTextPoint drawText) {
method copyDrawPoint (line 119) | public static DrawPoint copyDrawPoint(DrawPoint drawPoint) {
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/DrawTextPoint.java
class DrawTextPoint (line 9) | public class DrawTextPoint {
method getId (line 61) | public long getId() {
method setId (line 72) | public void setId(long id) {
method getX (line 83) | public float getX() {
method setX (line 94) | public void setX(float x) {
method getY (line 105) | public float getY() {
method setY (line 116) | public void setY(float y) {
method getStr (line 127) | public String getStr() {
method setStr (line 138) | public void setStr(String str) {
method getIsUnderline (line 149) | public boolean getIsUnderline() {
method setIsUnderline (line 160) | public void setIsUnderline(boolean isUnderline) {
method getIsItalics (line 171) | public boolean getIsItalics() {
method setIsItalics (line 182) | public void setIsItalics(boolean isItalics) {
method getIsBold (line 193) | public boolean getIsBold() {
method setIsBold (line 204) | public void setIsBold(boolean isBold) {
method getColor (line 215) | public int getColor() {
method setColor (line 226) | public void setColor(int color) {
method getStatus (line 237) | public int getStatus() {
method setStatus (line 248) | public void setStatus(int status) {
method getIsVisible (line 259) | public boolean getIsVisible() {
method setIsVisible (line 270) | public void setIsVisible(boolean isVisible) {
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/Point.java
class Point (line 6) | public class Point {
method Point (line 16) | public Point(){
method Point (line 18) | public Point(float x,float y){
method getX (line 29) | public float getX() {
method setX (line 40) | public void setX(float x) {
method getY (line 51) | public float getY() {
method setY (line 62) | public void setY(float y) {
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/WhiteBoardPoint.java
class WhiteBoardPoint (line 13) | public class WhiteBoardPoint {
method getId (line 37) | public int getId() {
method setId (line 47) | public void setId(int id) {
method getSavePoints (line 57) | public List<DrawPoint> getSavePoints() {
method getDeletePoints (line 70) | public List<DrawPoint> getDeletePoints() {
FILE: wblib/src/main/java/com/github/guanpy/wblib/bean/WhiteBoardPoints.java
class WhiteBoardPoints (line 9) | public class WhiteBoardPoints {
method getId (line 22) | public String getId() {
method setId (line 32) | public void setId(String id) {
method getWhiteBoardPoints (line 42) | public List<WhiteBoardPoint> getWhiteBoardPoints() {
method setWhiteBoardPoints (line 52) | public void setWhiteBoardPoints(List<WhiteBoardPoint> whiteBoardPoints) {
FILE: wblib/src/main/java/com/github/guanpy/wblib/utils/AppContextUtil.java
class AppContextUtil (line 11) | public class AppContextUtil {
method init (line 15) | public static void init(Context ctx) {
method getContext (line 19) | public static Context getContext() {
method getColor (line 23) | public static int getColor(int resId) {
method getString (line 30) | public static String getString(int resId) {
method getString (line 37) | public static String getString(int resId, Object... objs) {
method dip2px (line 47) | public static int dip2px(float dpValue) {
FILE: wblib/src/main/java/com/github/guanpy/wblib/utils/BeanUtil.java
class BeanUtil (line 8) | public class BeanUtil {
method CopyBeanToBean (line 20) | public static Object CopyBeanToBean(Object obj1, Object obj2) throws E...
FILE: wblib/src/main/java/com/github/guanpy/wblib/utils/Events.java
class Events (line 7) | public class Events {
FILE: wblib/src/main/java/com/github/guanpy/wblib/utils/OperationUtils.java
class OperationUtils (line 16) | public class OperationUtils {
method getInstance (line 86) | public static OperationUtils getInstance() {
method OperationUtils (line 96) | private OperationUtils() {
method init (line 102) | public void init() {
method getDrawPointList (line 120) | public WhiteBoardPoint getDrawPointList(int i) {
method getDrawPointSize (line 140) | public int getDrawPointSize() {
method getWhiteBoardPoints (line 152) | public WhiteBoardPoints getWhiteBoardPoints() {
method setWhiteBoardPoints (line 159) | public void setWhiteBoardPoints(WhiteBoardPoints whiteBoardPoints) {
method initDrawPointList (line 166) | public void initDrawPointList() {
method newPage (line 178) | public void newPage() {
method getNewMarkId (line 187) | public long getNewMarkId() {
method getSavePoints (line 194) | public List<DrawPoint> getSavePoints() {
method getDeletePoints (line 201) | public List<DrawPoint> getDeletePoints() {
FILE: wblib/src/main/java/com/github/guanpy/wblib/utils/WhiteBoardVariable.java
class WhiteBoardVariable (line 9) | public final class WhiteBoardVariable {
type Operation (line 11) | public interface Operation{
type Color (line 44) | public interface Color{
type PenSize (line 57) | public interface PenSize{
type EraserSize (line 66) | public interface EraserSize{
type RingSize (line 75) | public interface RingSize{
type TextStyle (line 82) | public interface TextStyle{
FILE: wblib/src/main/java/com/github/guanpy/wblib/widget/DrawPenView.java
class DrawPenView (line 26) | public class DrawPenView extends View {
method DrawPenView (line 57) | public DrawPenView(Context context, AttributeSet attr, int defStyle) {
method DrawPenView (line 62) | public DrawPenView(Context context, AttributeSet attr) {
method DrawPenView (line 67) | public DrawPenView(Context context) {
method initView (line 72) | private void initView(Context context) {
method init (line 79) | public void init(Paint paint) {
method initPaint (line 90) | private void initPaint() {
method changeEraser (line 105) | public void changeEraser() {
method setEraserSize (line 114) | public void setEraserSize() {
method setPenSize (line 121) | public void setPenSize() {
method setPenColor (line 128) | public void setPenColor() {
method onSizeChanged (line 133) | @Override
method onDraw (line 143) | @Override
method onTouchEvent (line 158) | @Override
method setPaint (line 219) | public void setPaint(Paint paint) {
method clearImage (line 231) | public void clearImage() {
method undo (line 242) | public void undo() {
method redo (line 248) | public void redo() {
method showPoints (line 255) | public void showPoints() {
FILE: wblib/src/main/java/com/github/guanpy/wblib/widget/DrawTextLayout.java
class DrawTextLayout (line 24) | public class DrawTextLayout extends FrameLayout {
method DrawTextLayout (line 33) | public DrawTextLayout(Context context, AttributeSet attrs) {
method DrawTextLayout (line 39) | public DrawTextLayout(Context context) {
method initView (line 44) | private void initView(Context context) {
method init (line 49) | public void init(Activity activity) {
method onTouchEvent (line 61) | @Override
method showPoints (line 95) | public void showPoints() {
method afterEdit (line 116) | public void afterEdit(boolean isSave){
method showNewPoint (line 120) | private void showNewPoint(DrawPoint dp) {
method onUpdate (line 131) | @Override
method updatePoint (line 139) | private void updatePoint(DrawPoint drawPoint) {
method setTextStyle (line 158) | public void setTextStyle(int changeStyle){
method setTextColor (line 183) | public void setTextColor(){
method undo (line 197) | public void undo(){
method redo (line 212) | public void redo(){
method dip2px (line 230) | public int dip2px(float dpValue) {
FILE: wblib/src/main/java/com/github/guanpy/wblib/widget/DrawTextView.java
class DrawTextView (line 26) | public class DrawTextView extends RelativeLayout implements
method DrawTextView (line 73) | public DrawTextView(Context context
method init (line 80) | private void init(Context context
method initUI (line 102) | private void initUI() {
method initEvent (line 124) | private void initEvent() {
method setText (line 189) | private void setText(String strText) {
method setLayoutParams (line 207) | private void setLayoutParams() {
method switchView (line 215) | public void switchView(int currentStatus) {
method afterEdit (line 268) | public void afterEdit(boolean isSave) {
method onClick (line 277) | @Override
type CallBackListener (line 300) | public interface CallBackListener {
method onUpdate (line 304) | void onUpdate(DrawPoint drawPoint);
method showSoftKeyBoard (line 307) | private void showSoftKeyBoard(final EditText et) {
method hideSoftInput (line 319) | private void hideSoftInput() {
Condensed preview — 91 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (237K chars).
[
{
"path": ".gitignore",
"chars": 475,
"preview": "#Android generated\nbin\ngen\nlint.xml\nlint\n\n#Eclipse\n.project\n.classpath\n.settings\n.checkstyle\n\n#IntelliJ IDEA\n.idea\n*.iml"
},
{
"path": "README.md",
"chars": 413,
"preview": "# WhiteBoard\n\n- 1、涂鸦功能:包括画笔粗细选择、颜色选择、橡皮擦等;\n- 2、文字输入:包括颜色选择、增、删、改等;\n- 3、白板功能:包括撤销、重做、新增、锁屏、切换、保存为图片、保存到本地等功能\n\n users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "settings.gradle",
"chars": 25,
"preview": "include ':app', ':wblib'\n"
},
{
"path": "wblib/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "wblib/build.gradle",
"chars": 530,
"preview": "apply plugin: 'com.android.library'\n\nandroid {\n compileSdkVersion 23\n buildToolsVersion \"23.0.3\"\n\n defaultConfi"
},
{
"path": "wblib/proguard-rules.pro",
"chars": 666,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in D:"
},
{
"path": "wblib/src/androidTest/java/com/github/guanpy/wblib/ApplicationTest.java",
"chars": 354,
"preview": "package com.github.guanpy.wblib;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a hr"
},
{
"path": "wblib/src/main/AndroidManifest.xml",
"chars": 271,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.github.guanpy.wblib\">\n\n <applic"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/bean/DrawPenPoint.java",
"chars": 1006,
"preview": "package com.github.guanpy.wblib.bean;\n\nimport android.graphics.Paint;\nimport android.graphics.Path;\n\n/**\n * 绘画存储-画笔路径\n *"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/bean/DrawPenStr.java",
"chars": 3639,
"preview": "package com.github.guanpy.wblib.bean;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * 绘画存储-画笔路径(字符串格式,方便储存)\n"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/bean/DrawPoint.java",
"chars": 2664,
"preview": "package com.github.guanpy.wblib.bean;\n\n\nimport com.github.guanpy.wblib.utils.BeanUtil;\n\npublic class DrawPoint {\n\n /*"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/bean/DrawTextPoint.java",
"chars": 4347,
"preview": "package com.github.guanpy.wblib.bean;\n\n/**\n * 绘画存储-文字\n * Created 2015-7-13 10:36:1\n *\n * @author gpy\n */\npublic class Dr"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/bean/Point.java",
"chars": 955,
"preview": "package com.github.guanpy.wblib.bean;\n\n/**\n * Created by gpy on 2015/8/21.\n */\npublic class Point {\n\n /**\n * X坐标\n"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/bean/WhiteBoardPoint.java",
"chars": 1248,
"preview": "package com.github.guanpy.wblib.bean;\n\n\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * 画板绘画路径存储\n *\n * @auth"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/bean/WhiteBoardPoints.java",
"chars": 1026,
"preview": "package com.github.guanpy.wblib.bean;\n\nimport java.util.List;\n\n/**\n * 画板合集\n * Created by gpy on 2015/8/21.\n */\npublic cl"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/utils/AppContextUtil.java",
"chars": 1164,
"preview": "package com.github.guanpy.wblib.utils;\n\nimport android.content.Context;\n\n/**\n * AppContextUtil\n *\n * @author yangz\n * @v"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/utils/BeanUtil.java",
"chars": 1735,
"preview": "package com.github.guanpy.wblib.utils;\n\nimport java.lang.reflect.Method;\n\n/**\n * Created by gpy on 2015/8/13.\n */\npublic"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/utils/Events.java",
"chars": 259,
"preview": "package com.github.guanpy.wblib.utils;\n\n/**\n * @author gpy\n * @version 2015/8/26.\n */\npublic class Events {\n\t/**\n\t * 白板相"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/utils/OperationUtils.java",
"chars": 5069,
"preview": "package com.github.guanpy.wblib.utils;\n\nimport com.github.guanpy.wblib.bean.DrawPoint;\nimport com.github.guanpy.wblib.be"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/utils/WhiteBoardVariable.java",
"chars": 2316,
"preview": "package com.github.guanpy.wblib.utils;\n\nimport com.github.guanpy.wblib.R;\n\n/**\n * 白板属性值汇总\n * Created by gpy on 2015/8/17"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/widget/DrawPenView.java",
"chars": 8720,
"preview": "package com.github.guanpy.wblib.widget;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android."
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/widget/DrawTextLayout.java",
"chars": 8983,
"preview": "package com.github.guanpy.wblib.widget;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.tex"
},
{
"path": "wblib/src/main/java/com/github/guanpy/wblib/widget/DrawTextView.java",
"chars": 11448,
"preview": "package com.github.guanpy.wblib.widget;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.gra"
},
{
"path": "wblib/src/main/res/drawable/draw_text_border.xml",
"chars": 292,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:sha"
},
{
"path": "wblib/src/main/res/layout/draw_text.xml",
"chars": 2664,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n an"
},
{
"path": "wblib/src/main/res/values/colors.xml",
"chars": 773,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#3F51B5</color>\n <color name=\"color"
},
{
"path": "wblib/src/main/res/values/strings.xml",
"chars": 68,
"preview": "<resources>\n <string name=\"app_name\">wblib</string>\n</resources>\n"
}
]
About this extraction
This page contains the full source code of the guanpy/WhiteBoard GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 91 files (209.6 KB), approximately 53.5k tokens, and a symbol index with 362 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.