data);
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/util/ActivityUtils.java
================================================
package com.lqm.tomatoit.util;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
/**
* autour: lqm
* desc:
*/
public class ActivityUtils {
private static final String TAG = "ActivityUtils";
public static void addFragmentToActivity(@NonNull FragmentManager fragmentManager,
@NonNull Fragment fragment, int frameId) {
addFragmentToActivity(fragmentManager, fragment, frameId, true);
}
public static void addFragmentToActivity(@NonNull FragmentManager fragmentManager,
@NonNull Fragment fragment, int frameId, boolean addToBackStack) {
if (fragment.isAdded()) {
Log.w(TAG, "addFragmentToActivity: fragment is added:" + fragment.getClass().getName());
return;
}
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(frameId, fragment);
if (addToBackStack) {
fragmentTransaction.addToBackStack(null);
}
fragmentTransaction.commit();
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/util/L.java
================================================
package com.lqm.tomatoit.util;
import android.util.Log;
/**
* Log统一管理类
*/
public class L {
private L() {
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
public static boolean isDebug = true;// 是否需要打印bug,可以在application的onCreate函数里面初始化
private static final String TAG = "way";
// 下面四个是默认tag的函数
public static void i(String msg) {
if (isDebug)
Log.i(TAG, msg);
}
public static void d(String msg) {
if (isDebug)
Log.d(TAG, msg);
}
public static void e(String msg) {
if (isDebug)
Log.e(TAG, msg);
}
public static void v(String msg) {
if (isDebug)
Log.v(TAG, msg);
}
// 下面是传入自定义tag的函数
public static void i(String tag, String msg) {
if (isDebug)
Log.i(tag, msg);
}
public static void d(String tag, String msg) {
if (isDebug)
Log.d(tag, msg);
}
public static void e(String tag, String msg) {
if (isDebug)
Log.e(tag, msg);
}
public static void v(String tag, String msg) {
if (isDebug)
Log.v(tag, msg);
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/util/PrefUtils.java
================================================
package com.lqm.tomatoit.util;
import android.content.Context;
import android.content.SharedPreferences;
/**
* autour: lqm
* desc: SharePreference的封装
*/
public class PrefUtils {
public static final String PREF_NAME = "config";
public static boolean getBoolean(Context ctx, String key,
boolean defaultValue) {
SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
Context.MODE_PRIVATE);
return sp.getBoolean(key, defaultValue);
}
public static void setBoolean(Context ctx, String key, boolean value) {
SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
Context.MODE_PRIVATE);
sp.edit().putBoolean(key, value).commit();
}
public static String getString(Context ctx, String key, String defaultValue) {
SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
Context.MODE_PRIVATE);
return sp.getString(key, defaultValue);
}
public static void setString(Context ctx, String key, String value) {
SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
Context.MODE_PRIVATE);
sp.edit().putString(key, value).commit();
}
public static int getInt(Context ctx, String key, int defaultValue) {
SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
Context.MODE_PRIVATE);
return sp.getInt(key, defaultValue);
}
public static void setInt(Context ctx, String key, int value) {
SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
Context.MODE_PRIVATE);
sp.edit().putInt(key, value).commit();
}
public static void clearData(Context ctx, String key) {
SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
sp.edit().remove(key).clear().commit();
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/util/SharesUtils.java
================================================
package com.lqm.tomatoit.util;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import com.lqm.tomatoit.R;
/**
* autour: lqm
* desc: 系统自带的分享
*/
public class SharesUtils {
public static void share(Context context, int stringRes) {
share(context, context.getString(stringRes));
}
public static void shareImage(Context context, Uri uri, String title) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.setType("image/jpeg");
context.startActivity(Intent.createChooser(shareIntent, title));
}
public static void share(Context context, String extraText) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.action_share));
intent.putExtra(Intent.EXTRA_TEXT, extraText);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(
Intent.createChooser(intent, context.getString(R.string.action_share)));
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/util/T.java
================================================
package com.lqm.tomatoit.util;
import android.content.Context;
import android.widget.Toast;
/**
* Toast统一管理类
*/
public class T {
private T() {
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
public static boolean isShow = true;
/**
* 短时间显示Toast
*
* @param context
* @param message
*/
public static void showShort(Context context, CharSequence message) {
if (isShow)
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
/**
* 短时间显示Toast
*
* @param context
* @param message
*/
public static void showShort(Context context, int message) {
if (isShow)
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
/**
* 长时间显示Toast
*
* @param context
* @param message
*/
public static void showLong(Context context, CharSequence message) {
if (isShow)
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
/**
* 长时间显示Toast
*
* @param context
* @param message
*/
public static void showLong(Context context, int message) {
if (isShow)
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
/**
* 自定义显示Toast时间
*
* @param context
* @param message
* @param duration
*/
public static void show(Context context, CharSequence message, int duration) {
if (isShow)
Toast.makeText(context, message, duration).show();
}
/**
* 自定义显示Toast时间
*
* @param context
* @param message
* @param duration
*/
public static void show(Context context, int message, int duration) {
if (isShow)
Toast.makeText(context, message, duration).show();
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/util/UIUtils.java
================================================
package com.lqm.tomatoit.util;
import android.content.Context;
import android.content.res.Resources;
import com.lqm.tomatoit.app.App;
/**
* @创建者 CSDN_LQR
* @描述 和ui相关的工具类
*/
public class UIUtils {
/**
* 得到上下文
*
* @return
*/
public static Context getContext() {
return App.getmContext();
}
/**
* 得到resources对象
*
* @return
*/
public static Resources getResource() {
return getContext().getResources();
}
/**
* 得到string.xml中的字符串
*
* @param resId
* @return
*/
public static String getString(int resId) {
return getResource().getString(resId);
}
/**
* 得到string.xml中的字符串,带点位符
*
* @return
*/
public static String getString(int id, Object... formatArgs) {
return getResource().getString(id, formatArgs);
}
/**
* 得到string.xml中和字符串数组
*
* @param resId
* @return
*/
public static String[] getStringArr(int resId) {
return getResource().getStringArray(resId);
}
/**
* 得到colors.xml中的颜色
* @param colorId
* @return
*/
public static int getColor(int colorId) {
return getResource().getColor(colorId);
}
/**
* dip-->px
*/
public static int dp2px(int dip) {
// px/dip = density;
// density = dpi/160
// 320*480 density = 1 1px = 1dp
// 1280*720 density = 2 2px = 1dp
float density = getResource().getDisplayMetrics().density;
int px = (int) (dip * density + 0.5f);
return px;
}
/**
* px-->dip
*/
public static int px2dp(int px) {
float density = getResource().getDisplayMetrics().density;
int dip = (int) (px / density + 0.5f);
return dip;
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/widget/AutoLinefeedLayout.java
================================================
package com.lqm.tomatoit.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
/**
* @user lqm
* @desc 自动换行布局
*/
public class AutoLinefeedLayout extends ViewGroup {
public AutoLinefeedLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public AutoLinefeedLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoLinefeedLayout(Context context) {
this(context, null);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
layoutHorizontal();
}
private void layoutHorizontal() {
final int count = getChildCount();
final int lineWidth = getMeasuredWidth() - getPaddingLeft()
- getPaddingRight();
int paddingTop = getPaddingTop();
int childTop = 0;
int childLeft = getPaddingLeft();
int availableLineWidth = lineWidth;
int maxLineHight = 0;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child == null) {
continue;
} else if (child.getVisibility() != GONE) {
final int childWidth = child.getMeasuredWidth();
final int childHeight = child.getMeasuredHeight();
if (availableLineWidth < childWidth) {
availableLineWidth = lineWidth;
paddingTop = paddingTop + maxLineHight;
childLeft = getPaddingLeft();
maxLineHight = 0;
}
childTop = paddingTop;
setChildFrame(child, childLeft, childTop, childWidth,
childHeight);
childLeft += childWidth;
availableLineWidth = availableLineWidth - childWidth;
maxLineHight = Math.max(maxLineHight, childHeight);
}
}
}
private void setChildFrame(View child, int left, int top, int width,
int height) {
child.layout(left, top, left + width, top + height);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int count = getChildCount();
for (int i = 0; i < count; i++) {
measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
}
if (heightMode == MeasureSpec.AT_MOST||heightMode == MeasureSpec.UNSPECIFIED) {
final int width = MeasureSpec.getSize(widthMeasureSpec);
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(
getDesiredHeight(width), MeasureSpec.EXACTLY));
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
private int getDesiredHeight(int width) {
final int lineWidth = width - getPaddingLeft() - getPaddingRight();
int availableLineWidth = lineWidth;
int totalHeight = getPaddingTop() + getPaddingBottom();
int lineHeight = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
final int childWidth = child.getMeasuredWidth();
final int childHeight = child.getMeasuredHeight();
if (availableLineWidth < childWidth) {
availableLineWidth = lineWidth;
totalHeight = totalHeight + lineHeight;
lineHeight = 0;
}
availableLineWidth = availableLineWidth - childWidth;
lineHeight = Math.max(childHeight, lineHeight);
}
totalHeight = totalHeight + lineHeight;
return totalHeight;
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/widget/CustomDialog.java
================================================
package com.lqm.tomatoit.widget;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
/**
* autour: lqm
* desc: 自定义圆角的dialog
*/
public class CustomDialog extends Dialog {
/**
* 宽高由布局文件中指定(但是最底层的宽度无效,可以多嵌套一层解决)
*/
public CustomDialog(Context context, View layout, int style) {
super(context, style);
setContentView(layout);
Window window = getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.CENTER;
window.setAttributes(params);
}
/**
* 宽高由该方法的参数设置
*/
public CustomDialog(Context context, int width, int height, View layout,
int style) {
super(context, style);
// 设置内容
setContentView(layout);
// 设置窗口属性
Window window = getWindow();
WindowManager.LayoutParams params = window.getAttributes();
// 设置宽度、高度、密度、对齐方式
float density = getDensity(context);
params.width = (int) (width * density);
params.height = (int) (height * density);
params.gravity = Gravity.CENTER;
window.setAttributes(params);
}
/**
* 获取显示密度
*
* @param context
* @return
*/
public float getDensity(Context context) {
Resources res = context.getResources();
DisplayMetrics dm = res.getDisplayMetrics();
return dm.density;
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/widget/CustomPopWindow.java
================================================
package com.lqm.tomatoit.widget;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.PopupWindow;
/**
* user:lqm
* desc:自定义PopWindow类,封装了PopWindow的一些常用属性,用Builder模式支持链式调用
* src:https://github.com/pinguo-zhouwei/CustomPopwindow
*/
public class CustomPopWindow implements PopupWindow.OnDismissListener{
private static final String TAG = "CustomPopWindow";
private static final float DEFAULT_ALPHA = 0.7f;
private Context mContext;
private int mWidth;
private int mHeight;
private boolean mIsFocusable = true;
private boolean mIsOutside = true;
private int mResLayoutId = -1;
private View mContentView;
private PopupWindow mPopupWindow;
private int mAnimationStyle = -1;
private boolean mClippEnable = true;//default is true
private boolean mIgnoreCheekPress = false;
private int mInputMode = -1;
private PopupWindow.OnDismissListener mOnDismissListener;
private int mSoftInputMode = -1;
private boolean mTouchable = true;//default is ture
private View.OnTouchListener mOnTouchListener;
private Window mWindow;//当前Activity 的窗口
/**
* 弹出PopWindow 背景是否变暗,默认不会变暗。
*/
private boolean mIsBackgroundDark = false;
private float mBackgroundDrakValue = 0;// 背景变暗的值,0 - 1
/**
* 设置是否允许点击 PopupWindow之外的地方,关闭PopupWindow
*/
private boolean enableOutsideTouchDisMiss = true;// 默认点击pop之外的地方可以关闭
private CustomPopWindow(Context context){
mContext = context;
}
public int getWidth() {
return mWidth;
}
public int getHeight() {
return mHeight;
}
/**
*
* @param anchor
* @param xOff
* @param yOff
* @return
*/
public CustomPopWindow showAsDropDown(View anchor, int xOff, int yOff){
if(mPopupWindow!=null){
mPopupWindow.showAsDropDown(anchor,xOff,yOff);
}
return this;
}
public CustomPopWindow showAsDropDown(View anchor){
if(mPopupWindow!=null){
mPopupWindow.showAsDropDown(anchor);
}
return this;
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public CustomPopWindow showAsDropDown(View anchor, int xOff, int yOff, int gravity){
if(mPopupWindow!=null){
mPopupWindow.showAsDropDown(anchor,xOff,yOff,gravity);
}
return this;
}
/**
* 相对于父控件的位置(通过设置Gravity.CENTER,下方Gravity.BOTTOM等 ),可以设置具体位置坐标
* @param parent 父控件
* @param gravity
* @param x the popup's x location offset
* @param y the popup's y location offset
* @return
*/
public CustomPopWindow showAtLocation(View parent, int gravity, int x, int y){
if(mPopupWindow!=null){
mPopupWindow.showAtLocation(parent,gravity,x,y);
}
return this;
}
/**
* 添加一些属性设置
* @param popupWindow
*/
private void apply(PopupWindow popupWindow){
popupWindow.setClippingEnabled(mClippEnable);
if(mIgnoreCheekPress){
popupWindow.setIgnoreCheekPress();
}
if(mInputMode!=-1){
popupWindow.setInputMethodMode(mInputMode);
}
if(mSoftInputMode!=-1){
popupWindow.setSoftInputMode(mSoftInputMode);
}
if(mOnDismissListener!=null){
popupWindow.setOnDismissListener(mOnDismissListener);
}
if(mOnTouchListener!=null){
popupWindow.setTouchInterceptor(mOnTouchListener);
}
popupWindow.setTouchable(mTouchable);
}
private PopupWindow build(){
if(mContentView == null){
mContentView = LayoutInflater.from(mContext).inflate(mResLayoutId,null);
}
// 2017.3.17 add
// 获取当前Activity的window
Activity activity = (Activity) mContentView.getContext();
if(activity!=null && mIsBackgroundDark){
//如果设置的值在0 - 1的范围内,则用设置的值,否则用默认值
final float alpha = (mBackgroundDrakValue > 0 && mBackgroundDrakValue < 1) ? mBackgroundDrakValue : DEFAULT_ALPHA;
mWindow = activity.getWindow();
WindowManager.LayoutParams params = mWindow.getAttributes();
params.alpha = alpha;
mWindow.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
mWindow.setAttributes(params);
}
if(mWidth != 0 && mHeight!=0 ){
mPopupWindow = new PopupWindow(mContentView,mWidth,mHeight);
}else{
mPopupWindow = new PopupWindow(mContentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
if(mAnimationStyle!=-1){
mPopupWindow.setAnimationStyle(mAnimationStyle);
}
apply(mPopupWindow);//设置一些属性
if(mWidth == 0 || mHeight == 0){
mPopupWindow.getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
//如果外面没有设置宽高的情况下,计算宽高并赋值
mWidth = mPopupWindow.getContentView().getMeasuredWidth();
mHeight = mPopupWindow.getContentView().getMeasuredHeight();
}
// 添加dissmiss 监听
mPopupWindow.setOnDismissListener(this);
//2017.6.27 add:fix 设置 setOutsideTouchable(false)点击外部取消的bug.
// 判断是否点击PopupWindow之外的地方关闭 popWindow
if(!enableOutsideTouchDisMiss){
//注意这三个属性必须同时设置,不然不能disMiss,以下三行代码在Android 4.4 上是可以,然后在Android 6.0以上,下面的三行代码就不起作用了,就得用下面的方法
mPopupWindow.setFocusable(true);
mPopupWindow.setOutsideTouchable(false);
mPopupWindow.setBackgroundDrawable(null);
//注意下面这三个是contentView 不是PopupWindow
mPopupWindow.getContentView().setFocusable(true);
mPopupWindow.getContentView().setFocusableInTouchMode(true);
mPopupWindow.getContentView().setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
mPopupWindow.dismiss();
return true;
}
return false;
}
});
//在Android 6.0以上 ,只能通过拦截事件来解决
mPopupWindow.setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
final int x = (int) event.getX();
final int y = (int) event.getY();
if ((event.getAction() == MotionEvent.ACTION_DOWN)
&& ((x < 0) || (x >= mWidth) || (y < 0) || (y >= mHeight))) {
Log.e(TAG,"out side ");
Log.e(TAG,"width:"+mPopupWindow.getWidth()+"height:"+mPopupWindow.getHeight()+" x:"+x+" y :"+y);
return true;
} else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
Log.e(TAG,"out side ...");
return true;
}
return false;
}
});
}else{
mPopupWindow.setFocusable(mIsFocusable);
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mPopupWindow.setOutsideTouchable(mIsOutside);
}
// update
mPopupWindow.update();
return mPopupWindow;
}
@Override
public void onDismiss() {
dissmiss();
}
/**
* 关闭popWindow
*/
public void dissmiss(){
if(mOnDismissListener!=null){
mOnDismissListener.onDismiss();
}
//如果设置了背景变暗,那么在dissmiss的时候需要还原
if(mWindow!=null){
WindowManager.LayoutParams params = mWindow.getAttributes();
params.alpha = 1.0f;
mWindow.setAttributes(params);
}
if(mPopupWindow!=null && mPopupWindow.isShowing()){
mPopupWindow.dismiss();
}
}
public PopupWindow getPopupWindow() {
return mPopupWindow;
}
public static class PopupWindowBuilder{
private CustomPopWindow mCustomPopWindow;
public PopupWindowBuilder(Context context){
mCustomPopWindow = new CustomPopWindow(context);
}
public PopupWindowBuilder size(int width,int height){
mCustomPopWindow.mWidth = width;
mCustomPopWindow.mHeight = height;
return this;
}
public PopupWindowBuilder setFocusable(boolean focusable){
mCustomPopWindow.mIsFocusable = focusable;
return this;
}
public PopupWindowBuilder setView(int resLayoutId){
mCustomPopWindow.mResLayoutId = resLayoutId;
mCustomPopWindow.mContentView = null;
return this;
}
public PopupWindowBuilder setView(View view){
mCustomPopWindow.mContentView = view;
mCustomPopWindow.mResLayoutId = -1;
return this;
}
public PopupWindowBuilder setOutsideTouchable(boolean outsideTouchable){
mCustomPopWindow.mIsOutside = outsideTouchable;
return this;
}
/**
* 设置弹窗动画
* @param animationStyle
* @return
*/
public PopupWindowBuilder setAnimationStyle(int animationStyle){
mCustomPopWindow.mAnimationStyle = animationStyle;
return this;
}
public PopupWindowBuilder setClippingEnable(boolean enable){
mCustomPopWindow.mClippEnable =enable;
return this;
}
public PopupWindowBuilder setIgnoreCheekPress(boolean ignoreCheekPress){
mCustomPopWindow.mIgnoreCheekPress = ignoreCheekPress;
return this;
}
public PopupWindowBuilder setInputMethodMode(int mode){
mCustomPopWindow.mInputMode = mode;
return this;
}
public PopupWindowBuilder setOnDissmissListener(PopupWindow.OnDismissListener onDissmissListener){
mCustomPopWindow.mOnDismissListener = onDissmissListener;
return this;
}
public PopupWindowBuilder setSoftInputMode(int softInputMode){
mCustomPopWindow.mSoftInputMode = softInputMode;
return this;
}
public PopupWindowBuilder setTouchable(boolean touchable){
mCustomPopWindow.mTouchable = touchable;
return this;
}
public PopupWindowBuilder setTouchIntercepter(View.OnTouchListener touchIntercepter){
mCustomPopWindow.mOnTouchListener = touchIntercepter;
return this;
}
/**
* 设置背景变暗是否可用
* @param isDark
* @return
*/
public PopupWindowBuilder enableBackgroundDark(boolean isDark){
mCustomPopWindow.mIsBackgroundDark = isDark;
return this;
}
/**
* 设置背景变暗的值
* @param darkValue
* @return
*/
public PopupWindowBuilder setBgDarkAlpha(float darkValue){
mCustomPopWindow.mBackgroundDrakValue = darkValue;
return this;
}
/**
* 设置是否允许点击 PopupWindow之外的地方,关闭PopupWindow
* @param disMiss
* @return
*/
public PopupWindowBuilder enableOutsideTouchableDissmiss(boolean disMiss){
mCustomPopWindow.enableOutsideTouchDisMiss = disMiss;
return this;
}
public CustomPopWindow create(){
//构建PopWindow
mCustomPopWindow.build();
return mCustomPopWindow;
}
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/widget/DynamicWave.java
================================================
package com.lqm.tomatoit.widget;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import com.lqm.tomatoit.R;
import com.lqm.tomatoit.util.UIUtils;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* autour: lqm
* desc: 水波纹效果View
* y = Asin(wx+b)+h:
* A:振幅两个山峰最大的高度.如果A越大两个山峰越高和越低
* h:你正弦曲线和y轴相交点.(影响正弦图初始高度的位置)
* b:初相会让你图片向x轴平移
* src: http://blog.csdn.net/qfanmingyiq/article/details/53038262
*
* 修改者: Notzuonotdied
*/
public class DynamicWave extends View {
/**
* 第一条水波移动速度
*/
private static final int TRANSLATE_X_SPEED_ONE = 7;
/**
* 第二条水波移动速度
*/
private static final int TRANSLATE_X_SPEED_TWO = 5;
/**
* 第三条水波移动速度s
*/
private static final int TRANSLATE_X_SPEED_THREE = 3;
private int mTotalWidth, mTotalHeight;
private ScheduledExecutorService executorService; //用于延迟绘制
/**
* 原始波纹的y值
*/
private float[] mYPositions;
/**
* 第一个波纹移动速度的像素值
*/
private int mXOffsetSpeedOne;
private int mXOffsetSpeedTwo;
private int mXOffsetSpeedThree;
/**
* 第一个波纹当前移动的距离
*/
private int mXOneOffset;
private int mXTwoOffset;
private int mXThreeOffset;
private Paint mWavePaint;
private DrawFilter mDrawFilter;
public DynamicWave(Context context, AttributeSet attrs) {
super(context, attrs);
// 将dp转化为px,用于控制不同分辨率上移动速度基本一致
mXOffsetSpeedOne = UIUtils.dp2px(TRANSLATE_X_SPEED_ONE);
mXOffsetSpeedTwo = UIUtils.dp2px(TRANSLATE_X_SPEED_TWO);
mXOffsetSpeedThree = UIUtils.dp2px(TRANSLATE_X_SPEED_THREE);
// 初始绘制波纹的画笔
mWavePaint = new Paint();
// 去除画笔锯齿
mWavePaint.setAntiAlias(true);
// 设置风格为实线
mWavePaint.setStyle(Paint.Style.FILL);
// 设置画笔颜色
mWavePaint.setColor(getResources().getColor(R.color.white));
mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
//
executorService = Executors
.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 从canvas层面去除绘制时锯齿
canvas.setDrawFilter(mDrawFilter);
// 控制波纹绘制的y在屏幕的位置,动态改变这个变量,可以形成波纹上升下降效果
for (int i = 0, j = 0, k = 0, f = 0; i < mTotalWidth; i++) {
if (i + mXOneOffset < mTotalWidth) {
canvas.drawLine(i, -mYPositions[mXOneOffset + i],
i, mTotalHeight, mWavePaint);
} else {
canvas.drawLine(i, -mYPositions[j],
i, mTotalHeight, mWavePaint);
j++;
}
if (i + mXTwoOffset < mTotalWidth) {
canvas.drawLine(i, -mYPositions[mXTwoOffset + i],
i, mTotalHeight, mWavePaint);
} else {
canvas.drawLine(i, -mYPositions[k],
i, mTotalHeight, mWavePaint);
k++;
}
if (i + mXThreeOffset < mTotalWidth) {
canvas.drawLine(i, -mYPositions[mXThreeOffset + i],
i, mTotalHeight, mWavePaint);
} else {
canvas.drawLine(i, -mYPositions[f],
i, mTotalHeight, mWavePaint);
f++;
}
}
// 改变两条波纹的移动点
mXOneOffset += mXOffsetSpeedOne;
mXTwoOffset += mXOffsetSpeedTwo;
mXThreeOffset += mXOffsetSpeedThree;
// 如果已经移动到结尾处,则重头记录
if (mXOneOffset >= mTotalWidth) {
mXOneOffset = 0;
}
if (mXTwoOffset > mTotalWidth) {
mXTwoOffset = 0;
}
if (mXThreeOffset > mTotalWidth) {
mXThreeOffset = 0;
}
// 引发view重绘,延迟233微秒绘制
executorService.schedule(this::invalidateWrap, 233, TimeUnit.MICROSECONDS);
}
/**
* 获取控件的高度和宽度
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 记录下view的宽高
mTotalWidth = w;
mTotalHeight = h;
// 用于保存原始波纹的y值
mYPositions = new float[mTotalWidth];
// y = Asin(wx+b)+h
// 将周期定为view总宽度
final float W = (float) (2 * Math.PI / mTotalWidth);
final float A = mTotalHeight / 2;
// 根据view总宽度得出所有对应的y值
for (int i = 0; i < mTotalWidth; i++) {
mYPositions[i] = (float) (A * Math.sin(W * i) - A);
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void invalidateWrap() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
postInvalidateOnAnimation();
} else {
postInvalidate();
}
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/widget/IconFontTextView.java
================================================
package com.lqm.tomatoit.widget;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
/**
* @user lqm
* @desc 使用IConFont TextView
*/
public class IconFontTextView extends android.support.v7.widget.AppCompatTextView {
private Context mContext;
public IconFontTextView(Context context) {
super(context);
mContext = context;
initView();
}
public IconFontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initView();
}
private void initView() {
Typeface iconfont = Typeface.createFromAsset(mContext.getAssets(), "iconfont.ttf");
setTypeface(iconfont);
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/widget/RoundImageView.java
================================================
package com.lqm.tomatoit.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorRes;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageView;
import com.lqm.tomatoit.R;
/**
* 自定义的圆角矩形ImageView
*/
@SuppressLint("AppCompatCustomView")
public class RoundImageView extends ImageView {
/**
* 图片的类型,圆形or圆角
*/
private int type;
public static final int TYPE_CIRCLE = 0;
public static final int TYPE_ROUND = 1;
public static final int TYPE_OVAL = 2;
/**
* 描边的颜色、宽度
*/
private int mBorderColor;
private float mBorderWidth;
private int mProgressColor = R.color.gray;
/**
* 圆角的大小
*/
private float mCornerRadius;
//左上角圆角大小
private float mLeftTopCornerRadius;
//右上角圆角大小
private float mRightTopCornerRadius;
//左下角圆角大小
private float mLeftBottomCornerRadius;
//右下角圆角大小
private float mRightBottomCornerRadius;
/**
* 绘图的Paint
*/
private Paint mBitmapPaint;
private Paint mBorderPaint;
/**
* 圆角的半径
*/
private float mRadius;
/**
* 3x3 矩阵,主要用于缩小放大
*/
private Matrix mMatrix;
/**
* 渲染图像,使用图像为绘制图形着色
*/
private BitmapShader mBitmapShader;
/**
* view的宽度
*/
private int mWidth;
/**
* 圆角图片区域
*/
private RectF mRoundRect;
private Path mRoundPath;
private int mBorderProgress = 0;
private static int num = 1;
public RoundImageView(Context context) {
this(context, null);
}
public RoundImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView, defStyleAttr, 0);
type = a.getInt(R.styleable.RoundImageView_type, TYPE_ROUND);
mBorderColor = a.getColor(R.styleable.RoundImageView_border_color, Color.WHITE);
mBorderWidth = a.getDimension(R.styleable.RoundImageView_border_width, 0);
mCornerRadius = a.getDimension(R.styleable.RoundImageView_corner_radius, dp2px(10));
mLeftTopCornerRadius = a.getDimension(R.styleable.RoundImageView_leftTop_corner_radius, 0);
mLeftBottomCornerRadius = a.getDimension(R.styleable.RoundImageView_leftBottom_corner_radius, 0);
mRightTopCornerRadius = a.getDimension(R.styleable.RoundImageView_rightTop_corner_radius, 0);
mRightBottomCornerRadius = a.getDimension(R.styleable.RoundImageView_rightBottom_corner_radius, 0);
a.recycle();
init();
}
private void init() {
mRoundPath = new Path();
mMatrix = new Matrix();
mBitmapPaint = new Paint();
mBitmapPaint.setAntiAlias(true);
mBorderPaint = new Paint();
mBorderPaint.setAntiAlias(true);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
/**
* 如果类型是圆形,则强制改变view的宽高一致,以小值为准
*/
if (type == TYPE_CIRCLE) {
mWidth = Math.min(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
mRadius = mWidth / 2 - mBorderWidth / 2;
setMeasuredDimension(mWidth, mWidth);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 圆角图片的范围
if (type == TYPE_ROUND || type == TYPE_OVAL) {
mRoundRect = new RectF(mBorderWidth / 2, mBorderWidth / 2, w - mBorderWidth / 2, h - mBorderWidth / 2);
}
}
@Override
protected void onDraw(Canvas canvas) {
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeWidth(mBorderWidth);
if (getDrawable() == null) {
return;
}
setUpShader();
if (type == TYPE_ROUND) {
setRoundPath();
canvas.drawPath(mRoundPath, mBitmapPaint);
//绘制描边
canvas.drawPath(mRoundPath, mBorderPaint);
} else if (type == TYPE_CIRCLE) {
canvas.drawCircle(mRadius + mBorderWidth / 2, mRadius + mBorderWidth / 2, mRadius, mBitmapPaint);
//绘制描边
canvas.drawCircle(mRadius + mBorderWidth / 2, mRadius + mBorderWidth / 2, mRadius, mBorderPaint);
//进度
mBorderPaint.setColor(getResources().getColor(mProgressColor));
RectF rect = new RectF(mBorderWidth/2,mBorderWidth/2,mRadius*2 + mBorderWidth/2,mRadius*2 + mBorderWidth/2);
canvas.drawArc(rect,-90,mBorderProgress,false,mBorderPaint);
} else {
canvas.drawOval(mRoundRect, mBitmapPaint);
canvas.drawOval(mRoundRect, mBorderPaint);
}
}
private void setRoundPath() {
mRoundPath.reset();
/**
* 如果四个圆角大小都是默认值0,
* 则将四个圆角大小设置为mCornerRadius的值
*/
if (mLeftTopCornerRadius == 0 &&
mLeftBottomCornerRadius == 0 &&
mRightTopCornerRadius == 0 &&
mRightBottomCornerRadius == 0) {
mRoundPath.addRoundRect(mRoundRect,
new float[]{mCornerRadius, mCornerRadius,
mCornerRadius, mCornerRadius,
mCornerRadius, mCornerRadius,
mCornerRadius, mCornerRadius},
Path.Direction.CW);
} else {
mRoundPath.addRoundRect(mRoundRect,
new float[]{mLeftTopCornerRadius, mLeftTopCornerRadius,
mRightTopCornerRadius, mRightTopCornerRadius,
mRightBottomCornerRadius, mRightBottomCornerRadius,
mLeftBottomCornerRadius, mLeftBottomCornerRadius},
Path.Direction.CW);
}
}
/**
* 初始化BitmapShader
*/
private void setUpShader() {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
Bitmap bmp = drawableToBitamp(drawable);
// 将bmp作为着色器,就是在指定区域内绘制bmp
mBitmapShader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
float scale = 1.0f;
if (type == TYPE_CIRCLE) {
// 拿到bitmap宽或高的小值
int bSize = Math.min(bmp.getWidth(), bmp.getHeight());
scale = mWidth * 1.0f / bSize;
//使缩放后的图片居中
float dx = (bmp.getWidth() * scale - mWidth) / 2;
float dy = (bmp.getHeight() * scale - mWidth) / 2;
mMatrix.setTranslate(-dx, -dy);
} else if (type == TYPE_ROUND || type == TYPE_OVAL) {
if (!(bmp.getWidth() == getWidth() && bmp.getHeight() == getHeight())) {
// 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值;
scale = Math.max(getWidth() * 1.0f / bmp.getWidth(),
getHeight() * 1.0f / bmp.getHeight());
//使缩放后的图片居中
float dx = (scale * bmp.getWidth() - getWidth()) / 2;
float dy = (scale * bmp.getHeight() - getHeight()) / 2;
mMatrix.setTranslate(-dx, -dy);
}
}
// shader的变换矩阵,我们这里主要用于放大或者缩小
mMatrix.preScale(scale, scale);
mBitmapShader.setLocalMatrix(mMatrix);
// 设置变换矩阵
mBitmapShader.setLocalMatrix(mMatrix);
// 设置shader
mBitmapPaint.setShader(mBitmapShader);
}
/**
* drawable转bitmap
*/
private Bitmap drawableToBitamp(Drawable drawable) {
try {
Bitmap bitmap;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bd = (BitmapDrawable) drawable;
return bd.getBitmap();
}
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
bitmap= Bitmap.createBitmap(w, h, drawable.getOpacity() != PixelFormat.OPAQUE
? Bitmap.Config.ARGB_4444 : Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
drawable.draw(canvas);
return bitmap;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
/**
* 设置图片类型:
* imageType=0 圆形图片
* imageType=1 圆角图片
* 默认为圆形图片
*/
public RoundImageView setType(int imageType) {
if (this.type != imageType) {
this.type = imageType;
if (this.type != TYPE_ROUND && this.type != TYPE_CIRCLE && this.type != TYPE_OVAL) {
this.type = TYPE_OVAL;
}
requestLayout();
}
return this;
}
/**
* 设置圆角图片的圆角大小
*/
public RoundImageView setCornerRadius(int cornerRadius) {
cornerRadius = dp2px(cornerRadius);
if (mCornerRadius != cornerRadius) {
mCornerRadius = cornerRadius;
invalidate();
}
return this;
}
/**
* 设置圆角图片的左上圆角大小
*/
public RoundImageView setLeftTopCornerRadius(int cornerRadius) {
cornerRadius = dp2px(cornerRadius);
if (mLeftTopCornerRadius != cornerRadius) {
mLeftTopCornerRadius = cornerRadius;
invalidate();
}
return this;
}
/**
* 设置圆角图片的右上圆角大小
*/
public RoundImageView setRightTopCornerRadius(int cornerRadius) {
cornerRadius = dp2px(cornerRadius);
if (mRightTopCornerRadius != cornerRadius) {
mRightTopCornerRadius = cornerRadius;
invalidate();
}
return this;
}
/**
* 设置圆角图片的左下圆角大小
*/
public RoundImageView setLeftBottomCornerRadius(int cornerRadius) {
cornerRadius = dp2px(cornerRadius);
if (mLeftBottomCornerRadius != cornerRadius) {
mLeftBottomCornerRadius = cornerRadius;
invalidate();
}
return this;
}
/**
* 设置圆角图片的右下圆角大小
*/
public RoundImageView setRightBottomCornerRadius(int cornerRadius) {
cornerRadius = dp2px(cornerRadius);
if (mRightBottomCornerRadius != cornerRadius) {
mRightBottomCornerRadius = cornerRadius;
invalidate();
}
return this;
}
/**
* 设置描边宽度
*/
public RoundImageView setBorderWidth(int borderWidth) {
borderWidth = dp2px(borderWidth);
if (mBorderWidth != borderWidth) {
mBorderWidth = borderWidth;
invalidate();
}
return this;
}
/**
* 设置描边颜色
*/
public RoundImageView setBorderColor(int borderColor) {
if (mBorderColor != borderColor) {
mBorderColor = borderColor;
invalidate();
}
return this;
}
private int dp2px(int dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, getResources().getDisplayMetrics());
}
public void setProgress(int progress,@ColorRes int color){
mBorderProgress = progress;
mProgressColor = color;
invalidate();
}
}
================================================
FILE: app/src/main/java/com/lqm/tomatoit/widget/WebViewFragment.java
================================================
package com.lqm.tomatoit.widget;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
/**
* 一个包含WebView的Fragment,来自Android Sdk
*/
public class WebViewFragment extends Fragment {
private WebView mWebView;
private boolean mIsWebViewAvailable;
public WebViewFragment() {
}
/**
* Called to instantiate the view. Creates and returns the WebView.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mWebView != null) {
mWebView.destroy();
}
mWebView = new WebView(getContext());
mIsWebViewAvailable = true;
return mWebView;
}
/**
* Called when the fragment is visible to the user and actively running. Resumes the WebView.
*/
@Override
public void onPause() {
super.onPause();
mWebView.onPause();
mWebView.pauseTimers();
}
/**
* Called when the fragment is no longer resumed. Pauses the WebView.
*/
@Override
public void onResume() {
mWebView.onResume();
mWebView.resumeTimers();
super.onResume();
}
/**
* Called when the WebView has been detached from the fragment.
* The WebView is no longer available after this time.
*/
@Override
public void onDestroyView() {
mIsWebViewAvailable = false;
super.onDestroyView();
}
/**
* Called when the fragment is no longer in use. Destroys the internal state of the WebView.
*/
@Override
public void onDestroy() {
if (mWebView != null) {
mWebView.destroy();
mWebView = null;
}
super.onDestroy();
}
/**
* Gets the WebView.
*/
public WebView getWebView() {
return mIsWebViewAvailable ? mWebView : null;
}
}
================================================
FILE: app/src/main/res/anim/slide_left_in.xml
================================================
================================================
FILE: app/src/main/res/anim/slide_left_out.xml
================================================
================================================
FILE: app/src/main/res/anim/slide_right_in.xml
================================================
================================================
FILE: app/src/main/res/anim/slide_right_out.xml
================================================
================================================
FILE: app/src/main/res/drawable/bg_round_frame_gray.xml
================================================
================================================
FILE: app/src/main/res/drawable/dialog_waiting.xml
================================================
================================================
FILE: app/src/main/res/drawable/progress_bar_status.xml
================================================
-
-
-
================================================
FILE: app/src/main/res/drawable/sel_menu_item.xml
================================================
================================================
FILE: app/src/main/res/drawable/shape_bg_round_white.xml
================================================
================================================
FILE: app/src/main/res/drawable/shape_tag_nor.xml
================================================
================================================
FILE: app/src/main/res/drawable/shape_tag_sel.xml
================================================
================================================
FILE: app/src/main/res/layout/activity_about.xml
================================================
================================================
FILE: app/src/main/res/layout/activity_collect.xml
================================================
================================================
FILE: app/src/main/res/layout/activity_login.xml
================================================
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
================================================
FILE: app/src/main/res/layout/activity_search.xml
================================================
================================================
FILE: app/src/main/res/layout/activity_webview.xml
================================================
================================================
FILE: app/src/main/res/layout/dialog_waiting.xml
================================================
================================================
FILE: app/src/main/res/layout/frag_home.xml
================================================
================================================
FILE: app/src/main/res/layout/frag_type.xml
================================================
================================================
FILE: app/src/main/res/layout/frag_user.xml
================================================
================================================
FILE: app/src/main/res/layout/item_article.xml
================================================
================================================
FILE: app/src/main/res/layout/item_banner.xml
================================================
================================================
FILE: app/src/main/res/layout/item_hot_key.xml
================================================
================================================
FILE: app/src/main/res/layout/item_no_data.xml
================================================
================================================
FILE: app/src/main/res/layout/item_tag_layout.xml
================================================
================================================
FILE: app/src/main/res/layout/layout_banner.xml
================================================
================================================
FILE: app/src/main/res/layout/layout_blank_tip.xml
================================================
================================================
FILE: app/src/main/res/layout/layout_topbar_home.xml
================================================
================================================
FILE: app/src/main/res/layout/layout_topbar_nor.xml
================================================
================================================
FILE: app/src/main/res/layout/popup_webview_more.xml
================================================
================================================
FILE: app/src/main/res/values/attrs.xml
================================================
================================================
FILE: app/src/main/res/values/colors.xml
================================================
#2395FF
#1189F8
#FF4081
#fff
#000
#5000
#e7e7e7
#0000
#2395FF
#F5F5F5
#3A3A3A
#FF5301
#FF8880
#A577FB
#8000
#464646
#7e7e7e
#969696
#c8969696
#DDDDDD
#EFEFEF
#969696
#2395FF
#FFFFFF
#FAFAFA
#FFFFFF
================================================
FILE: app/src/main/res/values/dimens.xml
================================================
48px
36px
28px
20px
24px
40px
105px
20px
58px
30px
98px
44px
98px
20px
30px
125px
65px
35px
24px
30px
28px
20px
7dp
38px
66px
//
================================================
FILE: app/src/main/res/values/strings.xml
================================================
玩Android
//
分享
复制链接
已复制链接
项目所用到的接口为鸿洋大神建立的玩安卓网站提供: www.wanandroid.com. \n\n
本项目源码地址为 https://github.com/luqinmao/TomatoIt. \n\n 哈哈,如果觉得可以的话给个start吧!\n\n
项目主要技术框架技术: \n\n okgo+ rxjava+mvp
================================================
FILE: app/src/main/res/values/styles.xml
================================================
================================================
FILE: app/src/test/java/com/lqm/tomatoit/ExampleUnitTest.java
================================================
package com.lqm.tomatoit;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see Testing documentation
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Tue Jan 02 09:34:21 CST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
================================================
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.
org.gradle.jvmargs=-Xmx1536m
# 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: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: iconfile/demo.css
================================================
*{margin: 0;padding: 0;list-style: none;}
/*
KISSY CSS Reset
理念:1. reset 的目的不是清除浏览器的默认样式,这仅是部分工作。清除和重置是紧密不可分的。
2. reset 的目的不是让默认样式在所有浏览器下一致,而是减少默认样式有可能带来的问题。
3. reset 期望提供一套普适通用的基础样式。但没有银弹,推荐根据具体需求,裁剪和修改后再使用。
特色:1. 适应中文;2. 基于最新主流浏览器。
维护:玉伯, 正淳
*/
/** 清除内外边距 **/
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* structural elements 结构元素 */
dl, dt, dd, ul, ol, li, /* list elements 列表元素 */
pre, /* text formatting elements 文本格式元素 */
form, fieldset, legend, button, input, textarea, /* form elements 表单元素 */
th, td /* table elements 表格元素 */ {
margin: 0;
padding: 0;
}
/** 设置默认字体 **/
body,
button, input, select, textarea /* for ie */ {
font: 12px/1.5 tahoma, arial, \5b8b\4f53, sans-serif;
}
h1, h2, h3, h4, h5, h6 { font-size: 100%; }
address, cite, dfn, em, var { font-style: normal; } /* 将斜体扶正 */
code, kbd, pre, samp { font-family: courier new, courier, monospace; } /* 统一等宽字体 */
small { font-size: 12px; } /* 小于 12px 的中文很难阅读,让 small 正常化 */
/** 重置列表元素 **/
ul, ol { list-style: none; }
/** 重置文本格式元素 **/
a { text-decoration: none; }
a:hover { text-decoration: underline; }
/** 重置表单元素 **/
legend { color: #000; } /* for ie6 */
fieldset, img { border: 0; } /* img 搭车:让链接里的 img 无边框 */
button, input, select, textarea { font-size: 100%; } /* 使得表单元素在 ie 下能继承字体大小 */
/* 注:optgroup 无法扶正 */
/** 重置表格元素 **/
table { border-collapse: collapse; border-spacing: 0; }
/* 清除浮动 */
.ks-clear:after, .clear:after {
content: '\20';
display: block;
height: 0;
clear: both;
}
.ks-clear, .clear {
*zoom: 1;
}
.main {
padding: 30px 100px;
width: 960px;
margin: 0 auto;
}
.main h1{font-size:36px; color:#333; text-align:left;margin-bottom:30px; border-bottom: 1px solid #eee;}
.helps{margin-top:40px;}
.helps pre{
padding:20px;
margin:10px 0;
border:solid 1px #e7e1cd;
background-color: #fffdef;
overflow: auto;
}
.icon_lists{
width: 100% !important;
}
.icon_lists li{
float:left;
width: 100px;
height:180px;
text-align: center;
list-style: none !important;
}
.icon_lists .icon{
font-size: 42px;
line-height: 100px;
margin: 10px 0;
color:#333;
-webkit-transition: font-size 0.25s ease-out 0s;
-moz-transition: font-size 0.25s ease-out 0s;
transition: font-size 0.25s ease-out 0s;
}
.icon_lists .icon:hover{
font-size: 100px;
}
.markdown {
color: #666;
font-size: 14px;
line-height: 1.8;
}
.highlight {
line-height: 1.5;
}
.markdown img {
vertical-align: middle;
max-width: 100%;
}
.markdown h1 {
color: #404040;
font-weight: 500;
line-height: 40px;
margin-bottom: 24px;
}
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
color: #404040;
margin: 1.6em 0 0.6em 0;
font-weight: 500;
clear: both;
}
.markdown h1 {
font-size: 28px;
}
.markdown h2 {
font-size: 22px;
}
.markdown h3 {
font-size: 16px;
}
.markdown h4 {
font-size: 14px;
}
.markdown h5 {
font-size: 12px;
}
.markdown h6 {
font-size: 12px;
}
.markdown hr {
height: 1px;
border: 0;
background: #e9e9e9;
margin: 16px 0;
clear: both;
}
.markdown p,
.markdown pre {
margin: 1em 0;
}
.markdown > p,
.markdown > blockquote,
.markdown > .highlight,
.markdown > ol,
.markdown > ul {
width: 80%;
}
.markdown ul > li {
list-style: circle;
}
.markdown > ul li,
.markdown blockquote ul > li {
margin-left: 20px;
padding-left: 4px;
}
.markdown > ul li p,
.markdown > ol li p {
margin: 0.6em 0;
}
.markdown ol > li {
list-style: decimal;
}
.markdown > ol li,
.markdown blockquote ol > li {
margin-left: 20px;
padding-left: 4px;
}
.markdown code {
margin: 0 3px;
padding: 0 5px;
background: #eee;
border-radius: 3px;
}
.markdown pre {
border-radius: 6px;
background: #f7f7f7;
padding: 20px;
}
.markdown pre code {
border: none;
background: #f7f7f7;
margin: 0;
}
.markdown strong,
.markdown b {
font-weight: 600;
}
.markdown > table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 95%;
margin-bottom: 24px;
}
.markdown > table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown > table th,
.markdown > table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown > table th {
background: #F7F7F7;
}
.markdown blockquote {
font-size: 90%;
color: #999;
border-left: 4px solid #e9e9e9;
padding-left: 0.8em;
margin: 1em 0;
font-style: italic;
}
.markdown blockquote p {
margin: 0;
}
.markdown .anchor {
opacity: 0;
transition: opacity 0.3s ease;
margin-left: 8px;
}
.markdown .waiting {
color: #ccc;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
opacity: 1;
display: inline-block;
}
.markdown > br,
.markdown > p > br {
clear: both;
}
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
pre{
background: #fff;
}
================================================
FILE: iconfile/demo_fontclass.html
================================================
IconFont
IconFont 图标
-
前进
.icon-qianjin
-
关于
.icon-guanyu
-
火
.icon-huo1
-
用户
.icon-yonghu
-
首页
.icon-1
-
删除关闭 叉2
.icon-shanchuguanbicha2
-
收藏
.icon-shoucang
-
更多
.icon-gengduo
-
3.0-搜索
.icon-sousuo
-
设置
.icon-shezhi
-
收藏
.icon-shoucang1
-
返回
.icon-fanhui
-
分享
.icon-fenxiang
-
右对齐
.icon-youduiqi
-
左对齐
.icon-zuoduiqi
-
分享
.icon-fenxiang1
-
分类
.icon-fenlei
-
返回
.icon-fanhui1
font-class引用
font-class是unicode使用方式的一种变种,主要是解决unicode书写不直观,语意不明确的问题。
与unicode使用方式相比,具有如下特点:
- 兼容性良好,支持ie8+,及所有现代浏览器。
- 相比于unicode语意明确,书写更直观。可以很容易分辨这个icon是什么。
- 因为使用class来定义图标,所以当要替换图标时,只需要修改class里面的unicode引用。
- 不过因为本质上还是使用的字体,所以多色图标还是不支持的。
使用步骤如下:
第一步:引入项目下面生成的fontclass代码:
第二步:挑选相应图标并获取类名,应用于页面:
<i class="iconfont icon-xxx"></i>
"iconfont"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。
================================================
FILE: iconfile/demo_symbol.html
================================================
IconFont
IconFont 图标
-
前进
#icon-qianjin
-
关于
#icon-guanyu
-
火
#icon-huo1
-
用户
#icon-yonghu
-
首页
#icon-1
-
删除关闭 叉2
#icon-shanchuguanbicha2
-
收藏
#icon-shoucang
-
更多
#icon-gengduo
-
3.0-搜索
#icon-sousuo
-
设置
#icon-shezhi
-
收藏
#icon-shoucang1
-
返回
#icon-fanhui
-
分享
#icon-fenxiang
-
右对齐
#icon-youduiqi
-
左对齐
#icon-zuoduiqi
-
分享
#icon-fenxiang1
-
分类
#icon-fenlei
-
返回
#icon-fanhui1
symbol引用
这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章
这种用法其实是做了一个svg的集合,与另外两种相比具有如下特点:
- 支持多色图标了,不再受单色限制。
- 通过一些技巧,支持像字体那样,通过
font-size,color来调整样式。
- 兼容性较差,支持 ie9+,及现代浏览器。
- 浏览器渲染svg的性能一般,还不如png。
使用步骤如下:
第一步:引入项目下面生成的symbol代码:
第二步:加入通用css代码(引入一次就行):
<style type="text/css">
.icon {
width: 1em; height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
第三步:挑选相应图标并获取类名,应用于页面:
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-xxx"></use>
</svg>
================================================
FILE: iconfile/demo_unicode.html
================================================
IconFont
IconFont 图标
-
前进

-
关于

-
火

-
用户

-
首页

-
删除关闭 叉2

-
收藏

-
更多

-
3.0-搜索

-
设置

-
收藏

-
返回

-
分享

-
右对齐

-
左对齐

-
分享

-
分类

-
返回

unicode引用
unicode是字体在网页端最原始的应用方式,特点是:
- 兼容性最好,支持ie6+,及所有现代浏览器。
- 支持按字体的方式去动态调整图标大小,颜色等等。
- 但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。
注意:新版iconfont支持多色图标,这些多色图标在unicode模式下将不能使用,如果有需求建议使用symbol的引用方式
unicode使用步骤如下:
第一步:拷贝项目下面生成的font-face
@font-face {
font-family: 'iconfont';
src: url('iconfont.eot');
src: url('iconfont.eot?#iefix') format('embedded-opentype'),
url('iconfont.woff') format('woff'),
url('iconfont.ttf') format('truetype'),
url('iconfont.svg#iconfont') format('svg');
}
第二步:定义使用iconfont的样式
.iconfont{
font-family:"iconfont" !important;
font-size:16px;font-style:normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
第三步:挑选相应图标并获取字体编码,应用于页面
<i class="iconfont">3</i>
"iconfont"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。
================================================
FILE: iconfile/iconfont.css
================================================
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1517475467488'); /* IE9*/
src: url('iconfont.eot?t=1517475467488#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
url('iconfont.ttf?t=1517475467488') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg?t=1517475467488#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family:"iconfont" !important;
font-size:16px;
font-style:normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-qianjin:before { content: "\e609"; }
.icon-guanyu:before { content: "\e7ca"; }
.icon-huo1:before { content: "\e66d"; }
.icon-yonghu:before { content: "\e652"; }
.icon-1:before { content: "\e611"; }
.icon-shanchuguanbicha2:before { content: "\e80b"; }
.icon-shoucang:before { content: "\e63b"; }
.icon-gengduo:before { content: "\e62b"; }
.icon-sousuo:before { content: "\e6a8"; }
.icon-shezhi:before { content: "\e604"; }
.icon-shoucang1:before { content: "\e63c"; }
.icon-fanhui:before { content: "\e617"; }
.icon-fenxiang:before { content: "\e63d"; }
.icon-youduiqi:before { content: "\e618"; }
.icon-zuoduiqi:before { content: "\e620"; }
.icon-fenxiang1:before { content: "\e66c"; }
.icon-fenlei:before { content: "\e654"; }
.icon-fanhui1:before { content: "\e6e5"; }
================================================
FILE: iconfile/iconfont.js
================================================
(function(window){var svgSprite='';var script=function(){var scripts=document.getElementsByTagName("script");return scripts[scripts.length-1]}();var shouldInjectCss=script.getAttribute("data-injectcss");var ready=function(fn){if(document.addEventListener){if(~["complete","loaded","interactive"].indexOf(document.readyState)){setTimeout(fn,0)}else{var loadFn=function(){document.removeEventListener("DOMContentLoaded",loadFn,false);fn()};document.addEventListener("DOMContentLoaded",loadFn,false)}}else if(document.attachEvent){IEContentLoaded(window,fn)}function IEContentLoaded(w,fn){var d=w.document,done=false,init=function(){if(!done){done=true;fn()}};var polling=function(){try{d.documentElement.doScroll("left")}catch(e){setTimeout(polling,50);return}init()};polling();d.onreadystatechange=function(){if(d.readyState=="complete"){d.onreadystatechange=null;init()}}}};var before=function(el,target){target.parentNode.insertBefore(el,target)};var prepend=function(el,target){if(target.firstChild){before(el,target.firstChild)}else{target.appendChild(el)}};function appendSvg(){var div,svg;div=document.createElement("div");div.innerHTML=svgSprite;svgSprite=null;svg=div.getElementsByTagName("svg")[0];if(svg){svg.setAttribute("aria-hidden","true");svg.style.position="absolute";svg.style.width=0;svg.style.height=0;svg.style.overflow="hidden";prepend(svg,document.body)}}if(shouldInjectCss&&!window.__iconfont__svg__cssinject__){window.__iconfont__svg__cssinject__=true;try{document.write("")}catch(e){console&&console.log(e)}}ready(appendSvg)})(window)
================================================
FILE: iconfile/用浏览器打开deni_unicode可以查看相关icon.txt
================================================
================================================
FILE: settings.gradle
================================================
include ':app'