onViewClickListener) {
137 | this.onViewClickListener = onViewClickListener;
138 | }
139 |
140 | public View createView(@NonNull ViewGroup parent, int viewType) {
141 | return LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
142 | }
143 |
144 | @Override
145 | public final void onBindViewHolder(@NonNull final VH holder, int position) {
146 | holder.itemView.setTag(position);
147 | addOnItemClickListener(holder);
148 | addOnItemLongClickListener(holder);
149 | bindViewHolder(holder, position, getItemAt(position), getItemViewType(position));
150 | }
151 |
152 | public abstract void bindViewHolder(@NonNull final VH holder, int position, T item, int viewType);
153 |
154 | @Override
155 | public int getItemCount() {
156 | return items.size();
157 | }
158 |
159 | private void addOnItemClickListener(@NonNull final VH holder){
160 | if (!itemClickEnable) return;
161 | if (onClickListener == null){
162 | onClickListener = new View.OnClickListener() {
163 | @Override
164 | public void onClick(View v) {
165 | int position = (int) v.getTag();
166 | if (onItemClickListener != null)
167 | onItemClickListener.onItemClick(v, position, getItemAt(position), getItemViewType(position));
168 | }
169 | };
170 | }
171 | holder.itemView.setOnClickListener(onClickListener);
172 | }
173 |
174 | private void addOnItemLongClickListener(@NonNull final VH holder){
175 | if (!itemLongClickEnable) return;
176 | if (onLongClickListener == null){
177 | onLongClickListener = new View.OnLongClickListener() {
178 | @Override
179 | public boolean onLongClick(View v) {
180 | int position = (int) v.getTag();
181 | if (onItemLongClickListener != null) {
182 | return onItemLongClickListener.onItemLongClick(v, position, getItemAt(position), getItemViewType(position));
183 | }
184 | return false;
185 | }
186 | };
187 | }
188 | holder.itemView.setOnLongClickListener(onLongClickListener);
189 | }
190 |
191 | public final void addOnViewClickListener(@NonNull final VH holder, @IdRes int id){
192 | //listener使用全局模式,避免每次都创建而造成内存d抖动
193 | if (listener == null)
194 | listener = new View.OnClickListener() {
195 | @Override
196 | public void onClick(View v) {
197 | int position = holder.getAdapterPosition();
198 | if (onViewClickListener != null)
199 | onViewClickListener.onItemClick(v, position, getItemAt(position), getItemViewType(position));
200 | }
201 | };
202 | View view = holder.itemView.findViewById(id);
203 | if (view != null)
204 | view.setOnClickListener(listener);
205 | }
206 | }
207 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/adapter/BlankSpaceItemDecoration.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.adapter;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Rect;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.View;
7 |
8 | /**
9 | * Black space line {@link android.support.v7.widget.RecyclerView.ItemDecoration} for {@link RecyclerView}.
10 | *
11 | *
Email:1006368252@qq.com
12 | *
QQ:1006368252
13 | *
https://github.com/JustinRoom/CameraMaskDemo
14 | *
15 | * @author jiangshicheng
16 | */
17 | public class BlankSpaceItemDecoration extends RecyclerView.ItemDecoration {
18 |
19 | int leftSpace;
20 | int topSpace;
21 | int rightSpace;
22 | int bottomSpace;
23 | boolean showFirstTop;
24 | boolean showLastBottom;
25 |
26 | public BlankSpaceItemDecoration(int leftSpace, int topSpace, int rightSpace, int bottomSpace) {
27 | this.leftSpace = leftSpace;
28 | this.topSpace = topSpace;
29 | this.rightSpace = rightSpace;
30 | this.bottomSpace = bottomSpace;
31 | }
32 |
33 | public void showFFTLB(boolean showFirstTop, boolean showLastBottom){
34 | this.showFirstTop = showFirstTop;
35 | this.showLastBottom = showLastBottom;
36 | }
37 |
38 | @Override
39 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
40 | super.getItemOffsets(outRect, view, parent, state);
41 | outRect.left = leftSpace;
42 | outRect.top = topSpace;
43 | outRect.right = rightSpace;
44 | outRect.bottom = bottomSpace;
45 | RecyclerView.Adapter adapter = parent.getAdapter();
46 | if (adapter != null && adapter.getItemCount() > 1) {
47 | if (!showFirstTop && parent.getChildAdapterPosition(view) == 0)
48 | outRect.top = 0;
49 |
50 | if (!showLastBottom && parent.getChildAdapterPosition(view) == adapter.getItemCount() - 1)
51 | outRect.bottom = 0;
52 | }
53 | }
54 |
55 | @Override
56 | public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
57 | super.onDraw(c, parent, state);
58 | }
59 |
60 | @Override
61 | public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
62 | super.onDrawOver(c, parent, state);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/adapter/ClassItemAdapter.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.adapter;
2 |
3 |
4 | import android.support.annotation.NonNull;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import jsc.exam.com.cameramask.R;
10 | import jsc.exam.com.cameramask.bean.ClassItem;
11 | import jsc.exam.com.cameramask.utils.CompatResourceUtils;
12 | import jsc.exam.com.cameramask.widgets.JSCItemLayout;
13 |
14 | public class ClassItemAdapter extends BaseRecyclerViewAdapter {
15 |
16 | public ClassItemAdapter() {
17 | }
18 |
19 | public ClassItemAdapter(int layoutId) {
20 | super(layoutId);
21 | }
22 |
23 | public ClassItemAdapter(int layoutId, boolean itemClickEnable, boolean itemLongClickEnable) {
24 | super(layoutId, itemClickEnable, itemLongClickEnable);
25 | }
26 |
27 | @Override
28 | public View createView(@NonNull ViewGroup parent, int viewType) {
29 | JSCItemLayout layout = new JSCItemLayout(parent.getContext());
30 | layout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, CompatResourceUtils.getDimensionPixelSize(parent, R.dimen.item_height)));
31 | layout.setBackgroundResource(R.drawable.ripple_round_corner_white_r4);
32 | layout.setPadding(
33 | CompatResourceUtils.getDimensionPixelSize(parent, R.dimen.space_8),
34 | 0,
35 | CompatResourceUtils.getDimensionPixelSize(parent, R.dimen.space_8),
36 | 0
37 | );
38 | layout.getLabelView().setPadding(
39 | CompatResourceUtils.getDimensionPixelSize(parent, R.dimen.space_12),
40 | 0,
41 | 0,
42 | 0
43 | );
44 | return layout;
45 | }
46 |
47 | @NonNull
48 | @Override
49 | public ClassItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
50 | JSCItemLayout v = (JSCItemLayout) createView(parent, viewType);
51 | return new ClassItemViewHolder(v);
52 | }
53 |
54 | @Override
55 | public void bindViewHolder(@NonNull ClassItemViewHolder holder, int position, ClassItem item, int viewType) {
56 | holder.layout.setLabel(item.getLabel());
57 | holder.layout.showDotView(item.isUpdated());
58 | }
59 |
60 | static class ClassItemViewHolder extends RecyclerView.ViewHolder {
61 |
62 | JSCItemLayout layout;
63 |
64 | ClassItemViewHolder(JSCItemLayout layout) {
65 | super(layout);
66 | this.layout = layout;
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/adapter/ViewAdapter.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.adapter;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | *
Email:1006368252@qq.com
7 | *
QQ:1006368252
8 | *
https://github.com/JustinRoom/CameraMaskDemo
9 | *
10 | * @author jiangshicheng
11 | */
12 | public interface ViewAdapter {
13 |
14 | public List getItems();
15 |
16 | public T getItemAt(int position);
17 |
18 | public void setItems(List items);
19 |
20 | public void addItems(List items);
21 |
22 | public void addItems(int position, List items);
23 |
24 | public void addItem(T item);
25 |
26 | public void addItem(int position, T item);
27 |
28 | public void removeItem(int position);
29 |
30 | public void removeItem(T item);
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/bean/ClassItem.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.bean;
2 |
3 | import android.support.annotation.IntDef;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | public class ClassItem {
9 | public static final int TYPE_ACTIVITY = 0;
10 | public static final int TYPE_FRAGMENT = 1;
11 | @IntDef({TYPE_ACTIVITY, TYPE_FRAGMENT})
12 | @Retention(RetentionPolicy.SOURCE)
13 | public @interface Type {
14 | }
15 |
16 | private String label;
17 | private Class> clazz;
18 | private int type;
19 | private boolean updated;
20 | private boolean isLandscape;
21 | private boolean fullScreen;
22 |
23 | public ClassItem() {
24 | }
25 |
26 | public ClassItem(@Type int type, String label, Class> clazz, boolean updated) {
27 | this(type, label, clazz, updated, false, false);
28 | }
29 | public ClassItem(@Type int type, String label, Class> clazz, boolean updated, boolean isLandscape, boolean fullScreen) {
30 | this.type = type;
31 | this.label = label;
32 | this.clazz = clazz;
33 | this.updated = updated;
34 | this.isLandscape = isLandscape;
35 | this.fullScreen = fullScreen;
36 | }
37 |
38 | public String getLabel() {
39 | return label;
40 | }
41 |
42 | public void setLabel(String label) {
43 | this.label = label;
44 | }
45 |
46 | public Class> getClazz() {
47 | return clazz;
48 | }
49 |
50 | public void setClazz(Class> clazz) {
51 | this.clazz = clazz;
52 | }
53 |
54 | public boolean isUpdated() {
55 | return updated;
56 | }
57 |
58 | public void setUpdated(boolean updated) {
59 | this.updated = updated;
60 | }
61 |
62 | public void setType(@Type int type) {
63 | this.type = type;
64 | }
65 |
66 | public int getType() {
67 | return type;
68 | }
69 |
70 | public boolean isLandscape() {
71 | return isLandscape;
72 | }
73 |
74 | public void setLandscape(boolean landscape) {
75 | isLandscape = landscape;
76 | }
77 |
78 | public boolean isFullScreen() {
79 | return fullScreen;
80 | }
81 |
82 | public void setFullScreen(boolean fullScreen) {
83 | this.fullScreen = fullScreen;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/fragments/AboutFragment.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.fragments;
2 |
3 | import android.content.DialogInterface;
4 | import android.content.Intent;
5 | import android.content.pm.PackageInfo;
6 | import android.content.pm.PackageManager;
7 | import android.net.Uri;
8 | import android.os.Bundle;
9 | import android.support.annotation.NonNull;
10 | import android.support.annotation.Nullable;
11 | import android.support.v4.app.Fragment;
12 | import android.support.v7.app.AlertDialog;
13 | import android.util.Log;
14 | import android.util.Pair;
15 | import android.view.LayoutInflater;
16 | import android.view.View;
17 | import android.view.ViewGroup;
18 | import android.widget.TextView;
19 | import android.widget.Toast;
20 |
21 | import org.json.JSONException;
22 | import org.json.JSONObject;
23 |
24 | import java.util.Locale;
25 |
26 | import io.reactivex.android.schedulers.AndroidSchedulers;
27 | import io.reactivex.disposables.Disposable;
28 | import io.reactivex.functions.Action;
29 | import io.reactivex.functions.Consumer;
30 | import io.reactivex.schedulers.Schedulers;
31 | import jsc.exam.com.cameramask.BuildConfig;
32 | import jsc.exam.com.cameramask.R;
33 | import jsc.exam.com.cameramask.retrofit.ApiService;
34 | import jsc.exam.com.cameramask.retrofit.CustomHttpClient;
35 | import jsc.exam.com.cameramask.retrofit.CustomRetrofit;
36 | import okhttp3.OkHttpClient;
37 | import retrofit2.Retrofit;
38 |
39 | /**
40 | *
Email:1006368252@qq.com
41 | *
QQ:1006368252
42 | *
https://github.com/JustinRoom/CameraMaskDemo
43 | *
44 | * @author jiangshicheng
45 | */
46 | public class AboutFragment extends Fragment {
47 |
48 | @Nullable
49 | @Override
50 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
51 | View root = inflater.inflate(R.layout.fragment_abount, container, false);
52 | TextView tvVersion = root.findViewById(R.id.tv_version);
53 | TextView tvUpdateContent = root.findViewById(R.id.tv_update_content);
54 | TextView tvBuildTime = root.findViewById(R.id.tv_build_time);
55 | try {
56 | PackageInfo packageInfo = inflater.getContext().getPackageManager().getPackageInfo(inflater.getContext().getPackageName(), PackageManager.GET_GIDS);
57 | tvVersion.setText(String.format(Locale.CHINA, "version:%s", packageInfo.versionName));
58 | } catch (PackageManager.NameNotFoundException e) {
59 | e.printStackTrace();
60 | }
61 | tvBuildTime.setText(String.format(Locale.CHINA, "build time:%s", BuildConfig.BUILD_TIME));
62 |
63 | root.findViewById(R.id.btn_check_update).setOnClickListener(new View.OnClickListener() {
64 | @Override
65 | public void onClick(View v) {
66 | v.setEnabled(false);
67 | checkUpdate();
68 | }
69 | });
70 | tvUpdateContent.setText("当前版本更新内容:" + getString(R.string.app_update_content));
71 | return root;
72 | }
73 |
74 | private void checkUpdate() {
75 | OkHttpClient client = new CustomHttpClient()
76 | .addHeader(new Pair<>("token", ""))
77 | .setConnectTimeout(5_000)
78 | .setShowLog(true)
79 | .createOkHttpClient();
80 | Retrofit retrofit = new CustomRetrofit()
81 | //我在app的build.gradle文件的defaultConfig标签里定义了BASE_URL
82 | .setBaseUrl(BuildConfig.BASE_URL)
83 | .setOkHttpClient(client)
84 | .createRetrofit();
85 | Disposable disposable = retrofit.create(ApiService.class)
86 | .getVersionInfo()
87 | .subscribeOn(Schedulers.io())
88 | .observeOn(AndroidSchedulers.mainThread())
89 | .subscribe(new Consumer() {
90 | @Override
91 | public void accept(String s) throws Exception {
92 | explainVersionInfoJson(s);
93 | }
94 | }, new Consumer() {
95 | @Override
96 | public void accept(Throwable throwable) throws Exception {
97 |
98 | }
99 | }, new Action() {
100 | @Override
101 | public void run() throws Exception {
102 | if (getView() != null) {
103 | getView().findViewById(R.id.btn_check_update).setEnabled(true);
104 | }
105 | }
106 | });
107 | }
108 |
109 | private void explainVersionInfoJson(String json) {
110 | json = json.substring(1, json.length() - 1);
111 | try {
112 | JSONObject object = new JSONObject(json).getJSONObject("apkInfo");
113 | int versionCode = object.getInt("versionCode");
114 | String versionName = object.getString("versionName");
115 | String fileName = object.getString("outputFile");
116 | String content = object.getString("content");
117 |
118 | PackageInfo packageInfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), PackageManager.GET_GIDS);
119 | long curVersionCode = packageInfo.versionCode;
120 | String curVersionName = packageInfo.versionName;
121 |
122 | Log.i("MainActivity", "explainVersionInfoJson: {versionCod" + versionCode + ", curVersionCode:" + curVersionCode);
123 | //a new version
124 | if (versionCode > curVersionCode) {
125 | showNewVersionDialog(String.format(
126 | Locale.CHINA,
127 | "当前版本:\u2000%1s\n"
128 | + "最新版本:\u2000%2s\n\n"
129 | + "更新内容:%3s"
130 | + "\n\n立即更新?",
131 | curVersionName,
132 | versionName,
133 | content
134 | ), fileName);
135 | } else {
136 | Toast.makeText(getActivity(), "已是最新版本!", Toast.LENGTH_SHORT).show();
137 | }
138 | } catch (JSONException | PackageManager.NameNotFoundException e) {
139 | e.printStackTrace();
140 | }
141 | }
142 |
143 | private void showNewVersionDialog(String content, final String fileName) {
144 | if (getActivity() == null)
145 | return;
146 |
147 | new AlertDialog.Builder(getActivity())
148 | .setTitle("新版本提示")
149 | .setMessage(content)
150 | .setPositiveButton("更新", new DialogInterface.OnClickListener() {
151 | @Override
152 | public void onClick(DialogInterface dialog, int which) {
153 | String url = BuildConfig.BASE_URL + BuildConfig.DOWNLOAD_URL;
154 | Uri uri = Uri.parse(String.format(Locale.CHINA, url, fileName));
155 | Intent intent = new Intent(Intent.ACTION_VIEW, uri);
156 | startActivity(intent);
157 |
158 | }
159 | })
160 | .setNegativeButton("知道了", null)
161 | .show();
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/fragments/CameraLensViewFragment.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.fragments;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.os.Bundle;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.support.v4.app.Fragment;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.ImageView;
13 | import android.widget.RadioGroup;
14 | import android.widget.SeekBar;
15 |
16 | import jsc.exam.com.cameramask.R;
17 | import jsc.exam.com.cameramask.widgets.dialog.BottomShowDialog;
18 | import jsc.kit.cameramask.CameraLensView;
19 |
20 | /**
21 | *
Email:1006368252@qq.com
22 | *
QQ:1006368252
23 | *
https://github.com/JustinRoom/CameraMaskDemo
24 | *
25 | * @author jiangshicheng
26 | */
27 | public class CameraLensViewFragment extends Fragment {
28 |
29 | private ImageView ivBackground;
30 | private CameraLensView cameraLensView;
31 | private Bitmap defaultCameraLensBitmap = null;
32 |
33 | @Nullable
34 | @Override
35 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
36 | View root = inflater.inflate(R.layout.fragment_camera_lens_view, container, false);
37 | initView(root);
38 | return root;
39 | }
40 |
41 | private void initView(View root) {
42 | ivBackground = root.findViewById(R.id.iv_background);
43 | cameraLensView = root.findViewById(R.id.camera_lens_view);
44 | RadioGroup typeRadioGroup = root.findViewById(R.id.radio_group_type);
45 | typeRadioGroup.check(R.id.radio_type_picture);
46 | typeRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
47 | @Override
48 | public void onCheckedChanged(RadioGroup group, int checkedId) {
49 | switch (checkedId) {
50 | case R.id.radio_type_picture:
51 | if (defaultCameraLensBitmap == null)
52 | defaultCameraLensBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.default_camera_lens);
53 | cameraLensView.setCameraLensBitmap(defaultCameraLensBitmap);
54 | break;
55 | case R.id.radio_type_normal:
56 | cameraLensView.setCameraLensBitmap(null);
57 | break;
58 | }
59 | }
60 | });
61 |
62 | RadioGroup shapeRadioGroup = root.findViewById(R.id.radio_group_shape);
63 | shapeRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
64 | @Override
65 | public void onCheckedChanged(RadioGroup group, int checkedId) {
66 | switch (checkedId) {
67 | case R.id.radio_shape_circle:
68 | cameraLensView.setCameraLensShape(CameraLensView.CIRCULAR);
69 | break;
70 | case R.id.radio_shape_square:
71 | cameraLensView.setCameraLensShape(CameraLensView.RECTANGLE);
72 | break;
73 | }
74 | }
75 | });
76 | RadioGroup locationRadioGroup = root.findViewById(R.id.radio_group_location);
77 | locationRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
78 | @Override
79 | public void onCheckedChanged(RadioGroup group, int checkedId) {
80 | switch (checkedId) {
81 | case R.id.radio_location_below:
82 | cameraLensView.setTextLocation(CameraLensView.BELOW_CAMERA_LENS);
83 | break;
84 | case R.id.radio_location_above:
85 | cameraLensView.setTextLocation(CameraLensView.ABOVE_CAMERA_LENS);
86 | break;
87 | }
88 | }
89 | });
90 |
91 | SeekBar topMarginSeekBar = root.findViewById(R.id.seek_bar_top_margin);
92 | topMarginSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
93 | @Override
94 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
95 | cameraLensView.setCameraLensTopMargin(progress);
96 | }
97 |
98 | @Override
99 | public void onStartTrackingTouch(SeekBar seekBar) {
100 |
101 | }
102 |
103 | @Override
104 | public void onStopTrackingTouch(SeekBar seekBar) {
105 |
106 | }
107 | });
108 |
109 | SeekBar textVerticalMarginSeekBar = root.findViewById(R.id.seek_bar_vertical_margin);
110 | textVerticalMarginSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
111 | @Override
112 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
113 | cameraLensView.setTextVerticalMargin(progress);
114 | }
115 |
116 | @Override
117 | public void onStartTrackingTouch(SeekBar seekBar) {
118 |
119 | }
120 |
121 | @Override
122 | public void onStopTrackingTouch(SeekBar seekBar) {
123 |
124 | }
125 | });
126 |
127 | root.findViewById(R.id.show_camera_lens_rect_bitmap).setOnClickListener(new View.OnClickListener() {
128 | @Override
129 | public void onClick(View v) {
130 | showCameraLensRectBitmap();
131 | }
132 | });
133 | }
134 |
135 | private void showCameraLensRectBitmap() {
136 | ivBackground.setDrawingCacheEnabled(true);
137 | Bitmap bitmap = ivBackground.getDrawingCache(true);
138 | bitmap = cameraLensView.cropCameraLensRectBitmap(bitmap, false);
139 | ImageView imageView = new ImageView(getContext());
140 | imageView.setImageBitmap(bitmap);
141 | BottomShowDialog dialog = new BottomShowDialog(getContext());
142 | dialog.setTitle("ShowBitmapInCameraLensRect");
143 | dialog.setBitmap(bitmap);
144 | dialog.show();
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/fragments/CameraScannerMaskViewFragment.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.fragments;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 | import jsc.exam.com.cameramask.R;
12 | import jsc.kit.cameramask.CameraScannerMaskView;
13 |
14 | /**
15 | *
Email:1006368252@qq.com
16 | *
QQ:1006368252
17 | *
https://github.com/JustinRoom/CameraMaskDemo
18 | *
19 | * @author jiangshicheng
20 | */
21 | public class CameraScannerMaskViewFragment extends Fragment {
22 |
23 | private CameraScannerMaskView cameraLensView;
24 |
25 | @Nullable
26 | @Override
27 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
28 | View root = inflater.inflate(R.layout.fragment_camera_scanner_mask_view, container, false);
29 | initView(root);
30 | return root;
31 | }
32 |
33 | private void initView(View root) {
34 | cameraLensView = root.findViewById(R.id.camera_scanner_mask_view);
35 | root.findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
36 | @Override
37 | public void onClick(View v) {
38 | cameraLensView.start();
39 | getView().findViewById(R.id.btn_start).setEnabled(false);
40 | getView().findViewById(R.id.btn_pause).setEnabled(true);
41 | getView().findViewById(R.id.btn_resume).setEnabled(false);
42 | getView().findViewById(R.id.btn_stop).setEnabled(true);
43 | }
44 | });
45 | root.findViewById(R.id.btn_pause).setOnClickListener(new View.OnClickListener() {
46 | @Override
47 | public void onClick(View v) {
48 | cameraLensView.pause();
49 | getView().findViewById(R.id.btn_start).setEnabled(false);
50 | getView().findViewById(R.id.btn_pause).setEnabled(false);
51 | getView().findViewById(R.id.btn_resume).setEnabled(true);
52 | getView().findViewById(R.id.btn_stop).setEnabled(true);
53 | }
54 | });
55 | root.findViewById(R.id.btn_resume).setOnClickListener(new View.OnClickListener() {
56 | @Override
57 | public void onClick(View v) {
58 | cameraLensView.resume();
59 | getView().findViewById(R.id.btn_start).setEnabled(false);
60 | getView().findViewById(R.id.btn_pause).setEnabled(true);
61 | getView().findViewById(R.id.btn_resume).setEnabled(false);
62 | getView().findViewById(R.id.btn_stop).setEnabled(true);
63 | }
64 | });
65 | root.findViewById(R.id.btn_stop).setOnClickListener(new View.OnClickListener() {
66 | @Override
67 | public void onClick(View v) {
68 | cameraLensView.stop();
69 | getView().findViewById(R.id.btn_start).setEnabled(true);
70 | getView().findViewById(R.id.btn_pause).setEnabled(false);
71 | getView().findViewById(R.id.btn_resume).setEnabled(false);
72 | getView().findViewById(R.id.btn_stop).setEnabled(false);
73 | }
74 | });
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/fragments/ScannerBarViewFragment.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.fragments;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.util.Log;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 |
12 | import jsc.exam.com.cameramask.R;
13 | import jsc.kit.cameramask.ScannerBarView;
14 |
15 | /**
16 | *
Email:1006368252@qq.com
17 | *
QQ:1006368252
18 | *
https://github.com/JustinRoom/CameraMaskDemo
19 | *
20 | * @author jiangshicheng
21 | */
22 | public class ScannerBarViewFragment extends Fragment {
23 |
24 | private static final String TAG = "ScannerBarViewFragment";
25 | ScannerBarView scannerBarView;
26 |
27 | @Override
28 | public void onCreate(@Nullable Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | Log.i(TAG, "onCreate: ");
31 | }
32 |
33 | @Nullable
34 | @Override
35 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
36 | Log.i(TAG, "onCreateView: ");
37 | View root = inflater.inflate(R.layout.fragment_scanner_bar_view, container, false);
38 | initView(root);
39 | return root;
40 | }
41 |
42 | private void initView(View root) {
43 | scannerBarView = root.findViewById(R.id.scanner_view);
44 | root.findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
45 | @Override
46 | public void onClick(View v) {
47 | scannerBarView.start();
48 | }
49 | });
50 | root.findViewById(R.id.btn_pause).setOnClickListener(new View.OnClickListener() {
51 | @Override
52 | public void onClick(View v) {
53 | scannerBarView.pause();
54 | }
55 | });
56 | root.findViewById(R.id.btn_resume).setOnClickListener(new View.OnClickListener() {
57 | @Override
58 | public void onClick(View v) {
59 | scannerBarView.resume();
60 | }
61 | });
62 | root.findViewById(R.id.btn_stop).setOnClickListener(new View.OnClickListener() {
63 | @Override
64 | public void onClick(View v) {
65 | scannerBarView.stop();
66 | }
67 | });
68 | root.findViewById(R.id.btn_change_size).setOnClickListener(new View.OnClickListener() {
69 | @Override
70 | public void onClick(View v) {
71 | ViewGroup.LayoutParams params = scannerBarView.getLayoutParams();
72 | params.width = getResources().getDimensionPixelSize(R.dimen.space_256);
73 | scannerBarView.setLayoutParams(params);
74 | }
75 | });
76 | root.findViewById(R.id.btn_change_img).setOnClickListener(new View.OnClickListener() {
77 | @Override
78 | public void onClick(View v) {
79 | scannerBarView.setScannerBarImageResource(R.drawable.camera_mask_scanner_line);
80 | }
81 | });
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/retrofit/ApiService.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.retrofit;
2 |
3 | import io.reactivex.Observable;
4 | import jsc.exam.com.cameramask.BuildConfig;
5 | import retrofit2.http.GET;
6 |
7 | public interface ApiService {
8 |
9 | @GET(BuildConfig.VERSION_URL)
10 | Observable getVersionInfo();
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/retrofit/CustomHttpClient.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.retrofit;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.util.Pair;
6 |
7 | import java.io.File;
8 | import java.io.IOException;
9 | import java.util.ArrayList;
10 | import java.util.List;
11 | import java.util.concurrent.TimeUnit;
12 |
13 | import io.reactivex.annotations.NonNull;
14 | import jsc.exam.com.cameramask.utils.ConnectivityHelper;
15 | import okhttp3.Cache;
16 | import okhttp3.CacheControl;
17 | import okhttp3.Interceptor;
18 | import okhttp3.OkHttpClient;
19 | import okhttp3.Request;
20 | import okhttp3.Response;
21 | import okhttp3.logging.HttpLoggingInterceptor;
22 |
23 | /**
24 | *
25 | *
Email:1006368252@qq.com
26 | *
QQ:1006368252
27 | *
https://github.com/JustinRoom/CameraMaskDemo
28 | *
29 | * create time: 6/6/2018 6:02 PM
30 | * @author jiangshicheng
31 | */
32 | public class CustomHttpClient {
33 | private boolean showLog = false;
34 | private int connectTimeout = 10_000;
35 | private int readTimeout = 10_000;
36 | private int writeTimeout = 10_000;
37 | private List> headers = null;
38 | private List interceptors = null;
39 | private Context context;
40 | private Cache cache;
41 |
42 | public CustomHttpClient setShowLog(boolean showLog) {
43 | this.showLog = showLog;
44 | return this;
45 | }
46 |
47 | public CustomHttpClient setConnectTimeout(int connectTimeout) {
48 | this.connectTimeout = connectTimeout;
49 | return this;
50 | }
51 |
52 | public CustomHttpClient setReadTimeout(int readTimeout) {
53 | this.readTimeout = readTimeout;
54 | return this;
55 | }
56 |
57 | public CustomHttpClient setWriteTimeout(int writeTimeout) {
58 | this.writeTimeout = writeTimeout;
59 | return this;
60 | }
61 |
62 | public CustomHttpClient addHeader(@NonNull Pair header) {
63 | if (headers == null) {
64 | headers = new ArrayList<>();
65 | }
66 | headers.add(header);
67 | return this;
68 | }
69 |
70 | public CustomHttpClient addInterceptor(Interceptor interceptor) {
71 | if (interceptors == null) {
72 | interceptors = new ArrayList<>();
73 | }
74 | interceptors.add(interceptor);
75 | return this;
76 | }
77 |
78 |
79 | public CustomHttpClient setContext(Application applicationContext) {
80 | this.context = applicationContext;
81 | return this;
82 | }
83 |
84 | /**
85 | * Set network cache config.
86 | * You must call method {@link #setContext(Application)} before calling this method.
87 | *
88 | * @param cacheFileName cache file name.
89 | * @param maxCacheSize cache max size.
90 | * @return CustomHttpClient
91 | */
92 | public CustomHttpClient setCache(String cacheFileName, long maxCacheSize) {
93 | if (context != null){
94 | File cacheFile = new File(context.getCacheDir(), cacheFileName);
95 | cache = new Cache(cacheFile, maxCacheSize);
96 | }
97 | return this;
98 | }
99 |
100 | public OkHttpClient createOkHttpClient() {
101 | OkHttpClient.Builder builder = new OkHttpClient.Builder();
102 | builder.connectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
103 | .readTimeout(readTimeout, TimeUnit.MILLISECONDS)
104 | .writeTimeout(writeTimeout, TimeUnit.MILLISECONDS);
105 | //拦截服务器端的Log日志并打印,如果未debug状态就打印日志,否则就什么都不做
106 | builder.addInterceptor(new HttpLoggingInterceptor().setLevel(showLog ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE));
107 |
108 | if (headers != null && !headers.isEmpty())
109 | builder.addInterceptor(createHeaderInterceptor());
110 |
111 | if (interceptors != null && !interceptors.isEmpty()) {
112 | for (Interceptor it : interceptors) {
113 | builder.addInterceptor(it);
114 | }
115 | }
116 |
117 | if (cache != null) {
118 | builder.cache(cache);
119 | builder.addNetworkInterceptor(createCacheInterceptor());
120 | }
121 | return builder.build();
122 | }
123 |
124 | private Interceptor createHeaderInterceptor() {
125 | return new Interceptor() {
126 | @Override
127 | public Response intercept(Chain chain) throws IOException {
128 | Request original = chain.request();
129 | Request.Builder requestBuilder = original.newBuilder();
130 | for (Pair header : headers) {
131 | requestBuilder.addHeader(header.first, header.second);
132 | }
133 | Request request = requestBuilder.build();
134 | return chain.proceed(request);
135 | }
136 | };
137 | }
138 |
139 | private Interceptor createCacheInterceptor() {
140 | return new Interceptor() {
141 | @Override
142 | public Response intercept(Chain chain) throws IOException {
143 | Request request = chain.request();
144 | // Add FORCE_CACHE cache control for each request if network is not available.
145 | if (!ConnectivityHelper.isNetworkAvailable(context)) {
146 | request = request.newBuilder()
147 | .cacheControl(CacheControl.FORCE_CACHE)
148 | .build();
149 | }
150 |
151 | Response originalResponse = chain.proceed(request);
152 | if (ConnectivityHelper.isNetworkAvailable(context)) {
153 | String cacheControl = request.cacheControl().toString();
154 | // Add cache control header for response same as request's while network is available.
155 | return originalResponse.newBuilder()
156 | .header("Cache-Control", cacheControl)
157 | .build();
158 | } else {
159 | // Add cache control header for response to FORCE_CACHE while network is not available.
160 | return originalResponse.newBuilder()
161 | .header("Cache-Control", CacheControl.FORCE_CACHE.toString())
162 | .build();
163 | }
164 | }
165 | };
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/retrofit/CustomRetrofit.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.retrofit;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import io.reactivex.annotations.NonNull;
7 | import okhttp3.OkHttpClient;
8 | import retrofit2.CallAdapter;
9 | import retrofit2.Converter;
10 | import retrofit2.Retrofit;
11 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
12 | import retrofit2.converter.gson.GsonConverterFactory;
13 | import retrofit2.converter.scalars.ScalarsConverterFactory;
14 |
15 | /**
16 | *
Email:1006368252@qq.com
17 | *
QQ:1006368252
18 | *
https://github.com/JustinRoom/CameraMaskDemo
19 | *
20 | * @author jiangshicheng
21 | */
22 | public class CustomRetrofit {
23 | private String baseUrl;
24 | private OkHttpClient okHttpClient;
25 | private List converterFactories = new ArrayList<>();
26 | private List callAdapterFactories = new ArrayList<>();
27 | private boolean isDefaultFactoriesAdded = false;
28 |
29 | public CustomRetrofit setBaseUrl(@NonNull String baseUrl) {
30 | this.baseUrl = baseUrl;
31 | return this;
32 | }
33 |
34 | public CustomRetrofit setOkHttpClient(@NonNull OkHttpClient okHttpClient) {
35 | this.okHttpClient = okHttpClient;
36 | return this;
37 | }
38 |
39 | private CustomRetrofit addConverterFactory(@NonNull Converter.Factory factory){
40 | checkIsDefaultFactoriesAdded();
41 | converterFactories.add(factory);
42 | return this;
43 | }
44 |
45 | private CustomRetrofit addCallAdapterFactory(@NonNull CallAdapter.Factory factory){
46 | checkIsDefaultFactoriesAdded();
47 | callAdapterFactories.add(factory);
48 | return this;
49 | }
50 |
51 | public Retrofit createRetrofit() {
52 | if (baseUrl == null || baseUrl.trim().length() == 0)
53 | throw new IllegalArgumentException("Base url can't be null.");
54 |
55 | if (okHttpClient == null)
56 | throw new IllegalArgumentException("You have not initialized OkHttpClient.");
57 |
58 | Retrofit.Builder builder = new Retrofit.Builder();
59 | builder.baseUrl(baseUrl).client(okHttpClient);
60 | checkIsDefaultFactoriesAdded();
61 | for (Converter.Factory factory : converterFactories) {
62 | builder.addConverterFactory(factory);
63 | }
64 | for (CallAdapter.Factory factory : callAdapterFactories) {
65 | builder.addCallAdapterFactory(factory);
66 | }
67 | return builder.build();
68 | }
69 |
70 | private void checkIsDefaultFactoriesAdded(){
71 | if (isDefaultFactoriesAdded)
72 | return;
73 |
74 | //增加返回值为String的支持
75 | converterFactories.add(ScalarsConverterFactory.create());
76 | //增加返回值为Gson的支持(以实体类返回)
77 | converterFactories.add(GsonConverterFactory.create());
78 | //增加返回值为Oservable的支持
79 | callAdapterFactories.add(RxJava2CallAdapterFactory.create());
80 | isDefaultFactoriesAdded = true;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/retrofit/LoadingDialogObserver.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.retrofit;
2 |
3 | import android.app.Dialog;
4 | import android.content.DialogInterface;
5 | import android.os.Handler;
6 | import android.os.Looper;
7 | import android.os.Message;
8 |
9 | import io.reactivex.Observer;
10 | import io.reactivex.disposables.Disposable;
11 |
12 | /**
13 | *
14 | *
Email:1006368252@qq.com
15 | *
QQ:1006368252
16 | *
https://github.com/JustinRoom/CameraMaskDemo
17 | *
18 | * create time: 6/7/2018 1:00 PM
19 | * @author jiangshicheng
20 | */
21 | public abstract class LoadingDialogObserver implements Observer, DialogInterface.OnCancelListener {
22 |
23 | private final int SHOW_DIALOG = 0x6990;
24 | private final int HIDE_DIALOG = 0x6991;
25 | private Dialog loadingDialog;
26 | private boolean ifShowDialog;
27 | private Handler handler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
28 | @Override
29 | public boolean handleMessage(Message message) {
30 | switch (message.what) {
31 | case SHOW_DIALOG:
32 | if (loadingDialog != null && !loadingDialog.isShowing())
33 | loadingDialog.show();
34 | break;
35 | case HIDE_DIALOG:
36 | if (loadingDialog != null && loadingDialog.isShowing())
37 | loadingDialog.dismiss();
38 | break;
39 | }
40 | return true;
41 | }
42 | });
43 | private Disposable disposable;
44 |
45 | /**
46 | * Constructor.
47 | */
48 | public LoadingDialogObserver() {
49 | this(null);
50 | }
51 |
52 | /**
53 | * Constructor.
54 | * @param loadingDialog loading dialog
55 | */
56 | public LoadingDialogObserver(Dialog loadingDialog) {
57 | this(loadingDialog, true);
58 | }
59 |
60 | /**
61 | * Constructor.
62 | *
63 | * @param loadingDialog loading dialog
64 | * @param ifShowDialog Show loadingDialog if true else not.
65 | */
66 | public LoadingDialogObserver(Dialog loadingDialog, boolean ifShowDialog) {
67 | this.loadingDialog = loadingDialog;
68 | this.ifShowDialog = ifShowDialog;
69 | if (loadingDialog != null)
70 | loadingDialog.setOnCancelListener(this);
71 | }
72 |
73 | @Override
74 | public void onSubscribe(Disposable d) {
75 | disposable = d;
76 | if (ifShowDialog)
77 | handler.sendEmptyMessage(SHOW_DIALOG);
78 | onStart(d);
79 | }
80 |
81 | @Override
82 | public void onNext(T t) {
83 | try {
84 | onResult(t);
85 | } catch (Exception e){
86 | onError(e);
87 | }
88 | }
89 |
90 | @Override
91 | public void onError(Throwable e) {
92 | if (ifShowDialog)
93 | handler.sendEmptyMessage(HIDE_DIALOG);
94 | onException(e);
95 | onCompleteOrCancel(disposable);
96 | }
97 |
98 | @Override
99 | public void onComplete() {
100 | if (ifShowDialog)
101 | handler.sendEmptyMessage(HIDE_DIALOG);
102 | onCompleteOrCancel(disposable);
103 | }
104 |
105 | @Override
106 | public void onCancel(DialogInterface dialog) {
107 | disposable.dispose();
108 | onCompleteOrCancel(disposable);
109 | }
110 |
111 | /**
112 | * Show loading dialog here if necessary.
113 | * @param disposable disposable, the same as the return of {@link io.reactivex.Observable#subscribe(Observer)}.
114 | */
115 | public abstract void onStart(Disposable disposable);
116 |
117 | /**
118 | * Call back the response.
119 | * @param t response
120 | */
121 | public abstract void onResult(T t);
122 |
123 | /**
124 | * Call back when a exception appears.
125 | * @param e exception
126 | */
127 | public abstract void onException(Throwable e);
128 |
129 | /**
130 | * Call back when {@link Observer#onComplete()} or loading dialog is canceled.
131 | * @param disposable disposable, the same as the return of {@link io.reactivex.Observable#subscribe(Observer)}.
132 | */
133 | public abstract void onCompleteOrCancel(Disposable disposable);
134 | }
135 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/utils/CompatResourceUtils.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.utils;
2 |
3 | import android.content.Context;
4 | import android.graphics.drawable.Drawable;
5 | import android.support.annotation.ColorRes;
6 | import android.support.annotation.DimenRes;
7 | import android.support.annotation.DrawableRes;
8 | import android.support.annotation.NonNull;
9 | import android.support.v4.app.Fragment;
10 | import android.util.TypedValue;
11 | import android.view.View;
12 |
13 | /**
14 | *
Email:1006368252@qq.com
15 | *
QQ:1006368252
16 | *
https://github.com/JustinRoom/CameraMaskDemo
17 | *
18 | * @author jiangshicheng
19 | */
20 | public class CompatResourceUtils {
21 |
22 | //color
23 | public static int getColor(@NonNull Context context, @ColorRes int resId){
24 | int color;
25 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
26 | color = context.getResources().getColor(resId, context.getTheme());
27 | } else {
28 | color = context.getResources().getColor(resId);
29 | }
30 | return color;
31 | }
32 |
33 | //drawable-xxhdpi
34 | public static Drawable getDrawable(@NonNull Context context, @DrawableRes int resId){
35 | Drawable drawable;
36 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
37 | drawable = context.getResources().getDrawable(resId, context.getTheme());
38 | } else {
39 | drawable = context.getResources().getDrawable(resId);
40 | }
41 | return drawable;
42 | }
43 |
44 | //dimension
45 | public static int getDimensionPixelSize(@NonNull Context context, @DimenRes int id){
46 | return context.getResources().getDimensionPixelSize(id);
47 | }
48 |
49 | public static int getDimensionPixelSize(@NonNull View view, @DimenRes int id){
50 | return view.getResources().getDimensionPixelSize(id);
51 | }
52 |
53 | public static int getDimensionPixelSize(@NonNull Fragment fragment, @DimenRes int id){
54 | return fragment.getResources().getDimensionPixelSize(id);
55 | }
56 |
57 | public static int dp2Px(@NonNull Context context, float dp){
58 | return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()) + .5f);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/utils/ConnectivityHelper.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.utils;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 |
7 | import java.util.Objects;
8 |
9 | /**
10 | *
11 | * ConnectivityHelper 网络工具
12 | *
13 | *
14 | */
15 | public class ConnectivityHelper {
16 |
17 | public static boolean isNetworkAvailable(Context context) {
18 | ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
19 | Objects.requireNonNull(cm);
20 | NetworkInfo networkInfo = cm.getActiveNetworkInfo();
21 | return networkInfo != null && networkInfo.isAvailable();
22 | }
23 |
24 | /**
25 | * 判断网络是否可用
26 | *
27 | * @param context context
28 | * @return boolean
29 | */
30 | public static boolean isConnectivityAvailable(Context context) {
31 | // 判断网络是否可用
32 | ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
33 | Objects.requireNonNull(cm);
34 | NetworkInfo info = cm.getActiveNetworkInfo();
35 | if (info == null || !info.isConnected()) {
36 | return false;
37 | }
38 | return info.isAvailable() || info.isRoaming();
39 | }
40 |
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/utils/WindowUtils.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.utils;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.graphics.drawable.Drawable;
7 | import android.os.Build;
8 | import android.support.annotation.NonNull;
9 | import android.util.TypedValue;
10 |
11 | /**
12 | *
Email:1006368252@qq.com
13 | *
QQ:1006368252
14 | *
https://github.com/JustinRoom/CameraMaskDemo
15 | *
16 | * @author jiangshicheng
17 | */
18 | public final class WindowUtils {
19 |
20 | /**
21 | * Get status bar height.
22 | *
23 | * @param context context
24 | * @return the height of status bar
25 | */
26 | public static int getStatusBarHeight(@NonNull Context context) {
27 | int statusBarHeight = 0;
28 | int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
29 | if (resourceId > 0) {
30 | statusBarHeight = CompatResourceUtils.getDimensionPixelSize(context, resourceId);
31 | }
32 | return statusBarHeight;
33 | }
34 |
35 | /**
36 | * Get action bar height.
37 | *
38 | * @param context context
39 | * @return the height of action bar
40 | */
41 | public static int getActionBarSize(@NonNull Context context) {
42 | TypedValue typedValue = new TypedValue();
43 | int[] attribute = new int[]{android.R.attr.actionBarSize};
44 | TypedArray array = context.obtainStyledAttributes(typedValue.resourceId, attribute);
45 | int actionBarSize = array.getDimensionPixelSize(0, 0);
46 | array.recycle();
47 | return actionBarSize;
48 | }
49 |
50 | /**
51 | * Get system selectable item background borderless.
52 | * @param context context
53 | * @return selectable item background borderless
54 | */
55 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
56 | public static Drawable getSelectableItemBackgroundBorderless(Context context){
57 | TypedValue typedValue = new TypedValue();
58 | context.getTheme().resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, typedValue, true);
59 | int[] attribute = new int[]{android.R.attr.selectableItemBackgroundBorderless};
60 | TypedArray typedArray = context.obtainStyledAttributes(typedValue.resourceId, attribute);
61 | Drawable drawable = typedArray.getDrawable(0);
62 | typedArray.recycle();
63 | return drawable;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/widgets/DotView.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.widgets;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.graphics.Outline;
6 | import android.graphics.Path;
7 | import android.os.Build;
8 | import android.support.annotation.IntDef;
9 | import android.support.annotation.IntRange;
10 | import android.support.annotation.Nullable;
11 | import android.support.v7.widget.AppCompatTextView;
12 | import android.util.AttributeSet;
13 | import android.util.Log;
14 | import android.view.Gravity;
15 | import android.view.View;
16 | import android.view.ViewOutlineProvider;
17 |
18 | import java.lang.annotation.Retention;
19 | import java.lang.annotation.RetentionPolicy;
20 |
21 | /**
22 | *
Email:1006368252@qq.com
23 | *
QQ:1006368252
24 | *
https://github.com/JustinRoom/CameraMaskDemo
25 | *
26 | * @author jiangshicheng
27 | */
28 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
29 | public class DotView extends AppCompatTextView {
30 |
31 | public final static int CIRCULAR = 0;
32 | public final static int SQUARE = 1;
33 | public final static int ROUND_CORNER_SQUARE = 2;
34 | public final static int TRIANGLE = 3;
35 | @IntDef({CIRCULAR, SQUARE, ROUND_CORNER_SQUARE, TRIANGLE})
36 | @Retention(RetentionPolicy.SOURCE)
37 | public @interface DotShape {
38 | }
39 |
40 | int shape = CIRCULAR;
41 | float radius = 0;
42 | int unReadCount = 0;
43 |
44 | public DotView(Context context) {
45 | super(context);
46 | initAttr(context, null, 0);
47 | }
48 |
49 | public DotView(Context context, @Nullable AttributeSet attrs) {
50 | super(context, attrs);
51 | initAttr(context, attrs, 0);
52 | }
53 |
54 | public DotView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
55 | super(context, attrs, defStyleAttr);
56 | initAttr(context, attrs, defStyleAttr);
57 | }
58 |
59 | private void initAttr(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
60 | setGravity(Gravity.CENTER);
61 | setClipToOutline(true);
62 | setOutlineProvider(new ViewOutlineProvider() {
63 | @Override
64 | public void getOutline(View view, Outline outline) {
65 | switch (shape){
66 | case CIRCULAR:
67 | outline.setOval(0, 0, view.getWidth(), view.getHeight());
68 | break;
69 | case SQUARE:
70 | outline.setRect(0, 0, view.getWidth(), view.getHeight());
71 | break;
72 | case ROUND_CORNER_SQUARE:
73 | outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), radius);
74 | break;
75 | case TRIANGLE:
76 | Path path = new Path();
77 | path.moveTo(view.getWidth() / 2.0f, 0);
78 | path.lineTo(0, view.getHeight());
79 | path.lineTo(view.getWidth(), view.getHeight());
80 | path.close();
81 | Log.i("DotView", "getOutline: isConvex =" + path.isConvex());
82 | outline.setConvexPath(path);
83 | break;
84 | }
85 | }
86 | });
87 | }
88 |
89 | public int getUnReadCount() {
90 | return unReadCount;
91 | }
92 |
93 | public void setUnReadCount(@IntRange(from = 0) int unReadCount) {
94 | this.unReadCount = unReadCount;
95 | if (unReadCount > 99)
96 | setText("99+");
97 | else if (unReadCount > 0)
98 | setText(String.valueOf(unReadCount));
99 | else
100 | setText("");
101 | }
102 |
103 | public void setShape(@DotShape int shape) {
104 | setShape(shape, 0);
105 | }
106 |
107 | public void setShape(@DotShape int dotShape, float roundRadius) {
108 | this.shape = dotShape;
109 | this.radius = roundRadius;
110 | invalidateOutline();
111 | }
112 |
113 | @Override
114 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
115 | super.onMeasure(widthMeasureSpec, widthMeasureSpec);
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/widgets/JSCItemLayout.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.widgets;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Color;
6 | import android.support.annotation.DrawableRes;
7 | import android.support.annotation.Nullable;
8 | import android.support.annotation.StringRes;
9 | import android.support.v7.widget.AppCompatImageView;
10 | import android.util.AttributeSet;
11 | import android.util.TypedValue;
12 | import android.view.Gravity;
13 | import android.view.ViewGroup;
14 | import android.widget.FrameLayout;
15 | import android.widget.ImageView;
16 | import android.widget.LinearLayout;
17 | import android.widget.TextView;
18 |
19 | import jsc.exam.com.cameramask.R;
20 | import jsc.exam.com.cameramask.utils.CompatResourceUtils;
21 |
22 | /**
23 | *
Email:1006368252@qq.com
24 | *
QQ:1006368252
25 | *
https://github.com/JustinRoom/CameraMaskDemo
26 | *
27 | * @author jiangshicheng
28 | */
29 | public class JSCItemLayout extends FrameLayout {
30 |
31 | private ImageView iconView;
32 | private TextView labelView;
33 | private TextView valueView;
34 | private DotView dotView;
35 | private ImageView arrowView;
36 |
37 | public JSCItemLayout(Context context) {
38 | super(context);
39 | initAttr(context, null, 0);
40 | }
41 |
42 | public JSCItemLayout(Context context, @Nullable AttributeSet attrs) {
43 | super(context, attrs);
44 | initAttr(context, attrs, 0);
45 | }
46 |
47 | public JSCItemLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
48 | super(context, attrs, defStyleAttr);
49 | initAttr(context, attrs, defStyleAttr);
50 | }
51 |
52 | private void initAttr(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
53 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.JSCItemLayout, defStyleAttr, 0);
54 |
55 | LayoutParams contentParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
56 | contentParams.gravity = Gravity.CENTER_VERTICAL;
57 | LinearLayout layout = new LinearLayout(context);
58 | layout.setOrientation(LinearLayout.HORIZONTAL);
59 | layout.setGravity(Gravity.CENTER_VERTICAL);
60 | addView(layout, contentParams);
61 |
62 | //icon
63 | iconView = new AppCompatImageView(context);
64 | iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
65 | layout.addView(iconView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
66 | iconView.setImageResource(a.getResourceId(R.styleable.JSCItemLayout_il_icon, R.drawable.kit_ic_assignment_blue_24dp));
67 |
68 | //label
69 | labelView = new TextView(context);
70 | labelView.setTextColor(0xFF666666);
71 | labelView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
72 | layout.addView(labelView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
73 | if (a.hasValue(R.styleable.JSCItemLayout_il_label)) {
74 | labelView.setText(a.getString(R.styleable.JSCItemLayout_il_label));
75 | }
76 |
77 | //value
78 | valueView = new TextView(context);
79 | valueView.setTextColor(0xFF333333);
80 | valueView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
81 | layout.addView(valueView, new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1));
82 | if (a.hasValue(R.styleable.JSCItemLayout_il_value)) {
83 | valueView.setText(a.getString(R.styleable.JSCItemLayout_il_value));
84 | }
85 |
86 | //red dot
87 | int size = CompatResourceUtils.getDimensionPixelSize(this, R.dimen.space_8);
88 | dotView = new DotView(context);
89 | dotView.setBackgroundColor(Color.RED);
90 | dotView.setTextColor(Color.WHITE);
91 | if (a.hasValue(R.styleable.JSCItemLayout_il_dotSize)){
92 | size = a.getDimensionPixelSize(R.styleable.JSCItemLayout_il_dotSize, 0);
93 | }
94 | dotView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
95 | layout.addView(dotView, new LinearLayout.LayoutParams(size, size));
96 | showDotView(a.getBoolean(R.styleable.JSCItemLayout_il_showDot, false));
97 |
98 | //right arrow
99 | arrowView = new AppCompatImageView(context);
100 | arrowView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
101 | layout.addView(arrowView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
102 | arrowView.setImageResource(a.getResourceId(R.styleable.JSCItemLayout_il_arrowIcon, R.drawable.kit_ic_chevron_right_gray_24dp));
103 |
104 | a.recycle();
105 | }
106 |
107 | public ImageView getIconView() {
108 | return iconView;
109 | }
110 |
111 | public TextView getLabelView() {
112 | return labelView;
113 | }
114 |
115 | public TextView getValueView() {
116 | return valueView;
117 | }
118 |
119 | public DotView getDotView() {
120 | return dotView;
121 | }
122 |
123 | public ImageView getArrowView() {
124 | return arrowView;
125 | }
126 |
127 | public void showIconView(boolean show) {
128 | iconView.setVisibility(show ? VISIBLE : GONE);
129 | }
130 |
131 | public void showDotView(boolean show) {
132 | dotView.setVisibility(show ? VISIBLE : GONE);
133 | }
134 |
135 | public void showArrowView(boolean show){
136 | arrowView.setVisibility(show ? VISIBLE : GONE);
137 | }
138 |
139 | public int getUnreadCount() {
140 | return dotView.getUnReadCount();
141 | }
142 |
143 | public void setUnreadCount(int unreadCount) {
144 | dotView.setUnReadCount(unreadCount);
145 | }
146 |
147 | public void setIcon(@DrawableRes int resId) {
148 | iconView.setImageResource(resId);
149 | }
150 |
151 | public void setLabel(CharSequence label) {
152 | labelView.setText(label);
153 | }
154 |
155 | public void setLabel(@StringRes int resId) {
156 | labelView.setText(resId);
157 | }
158 |
159 | public void setValue(CharSequence label) {
160 | valueView.setText(label);
161 | }
162 |
163 | public void setValue(@StringRes int resId) {
164 | valueView.setText(resId);
165 | }
166 |
167 | public void setArrow(@DrawableRes int resId) {
168 | arrowView.setImageResource(resId);
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/widgets/SquareImageView.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.widgets;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.AppCompatImageView;
5 | import android.util.AttributeSet;
6 |
7 | public class SquareImageView extends AppCompatImageView {
8 | public SquareImageView(Context context) {
9 | super(context);
10 | }
11 |
12 | public SquareImageView(Context context, AttributeSet attrs) {
13 | super(context, attrs);
14 | }
15 |
16 | public SquareImageView(Context context, AttributeSet attrs, int defStyleAttr) {
17 | super(context, attrs, defStyleAttr);
18 | }
19 |
20 | @Override
21 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
22 | super.onMeasure(widthMeasureSpec, widthMeasureSpec);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/jsc/exam/com/cameramask/widgets/dialog/BottomShowDialog.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask.widgets.dialog;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.graphics.Bitmap;
6 | import android.graphics.Color;
7 | import android.os.Bundle;
8 | import android.support.annotation.NonNull;
9 | import android.util.TypedValue;
10 | import android.view.Gravity;
11 | import android.view.ViewGroup;
12 | import android.view.Window;
13 | import android.view.WindowManager;
14 | import android.widget.ImageView;
15 | import android.widget.LinearLayout;
16 | import android.widget.TextView;
17 |
18 | import jsc.exam.com.cameramask.R;
19 |
20 | /**
21 | *
Email:1006368252@qq.com
22 | *
QQ:1006368252
23 | *
https://github.com/JustinRoom/CameraMaskDemo
24 | *
25 | * @author jiangshicheng
26 | */
27 | public class BottomShowDialog extends Dialog {
28 |
29 | CharSequence title;
30 | Bitmap bitmap;
31 |
32 | public BottomShowDialog( @NonNull Context context) {
33 | this(context, R.style.Theme_AppCompat_Dialog);
34 | }
35 |
36 | public BottomShowDialog( @NonNull Context context, int themeResId) {
37 | super(context, themeResId);
38 | }
39 |
40 | @Override
41 | protected void onCreate(Bundle savedInstanceState) {
42 | super.onCreate(savedInstanceState);
43 | requestWindowFeature(Window.FEATURE_NO_TITLE);
44 | LinearLayout layout = new LinearLayout(getContext());
45 | layout.setOrientation(LinearLayout.VERTICAL);
46 | layout.setGravity(Gravity.CENTER_HORIZONTAL);
47 | //
48 | TextView textView = new TextView(getContext());
49 | textView.setBackgroundColor(getContext().getResources().getColor(R.color.colorAccent));
50 | textView.setGravity(Gravity.CENTER_HORIZONTAL);
51 | textView.setText(title);
52 | textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
53 | textView.setTextColor(0xFF333333);
54 | textView.setPadding(0, 16, 0, 16);
55 | layout.addView(textView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
56 | //
57 | LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
58 | params.topMargin = 24;
59 | params.bottomMargin = 24;
60 | ImageView imageView = new ImageView(getContext());
61 | imageView.setImageBitmap(bitmap);
62 | layout.addView(imageView, params);
63 | setContentView(layout);
64 |
65 | if (getWindow() != null) {
66 | getWindow().setGravity(Gravity.BOTTOM);
67 | getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
68 | getWindow().setBackgroundDrawable(null);
69 | getWindow().getDecorView().setBackgroundColor(Color.WHITE);
70 | }
71 | }
72 |
73 | @Override
74 | public void show() {
75 | super.show();
76 | }
77 |
78 | @Override
79 | public void setTitle(CharSequence title) {
80 | this.title = title;
81 | }
82 |
83 | public void setBitmap(Bitmap bitmap) {
84 | this.bitmap = bitmap;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ripple_round_corner_white_r4.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | -
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/btn_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/drawable-xxhdpi/btn_background.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/default_camera_lens.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/drawable-xxhdpi/default_camera_lens.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_chevron_left_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/drawable-xxhdpi/ic_chevron_left_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/kit_ic_assignment_blue_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/drawable-xxhdpi/kit_ic_assignment_blue_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/kit_ic_chevron_right_gray_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/drawable-xxhdpi/kit_ic_chevron_right_gray_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/beauty_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/drawable/beauty_bg.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/camera_mask_demo_qr_code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/drawable/camera_mask_demo_qr_code.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ripple_round_corner_white_r4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 | -
12 |
13 |
14 |
15 |
16 |
17 |
18 | -
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_abount.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
22 |
23 |
31 |
32 |
40 |
41 |
49 |
50 |
51 |
52 |
57 |
58 |
66 |
67 |
76 |
77 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_camera_lens_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
29 |
30 |
36 |
37 |
42 |
43 |
50 |
51 |
60 |
61 |
62 |
63 |
68 |
69 |
76 |
77 |
86 |
87 |
88 |
89 |
94 |
95 |
102 |
103 |
111 |
112 |
113 |
114 |
120 |
121 |
127 |
128 |
134 |
135 |
141 |
142 |
143 |
144 |
150 |
151 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_camera_scanner_mask_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
24 |
25 |
30 |
31 |
36 |
37 |
43 |
44 |
50 |
51 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_scanner_bar_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
25 |
26 |
30 |
31 |
36 |
37 |
42 |
43 |
48 |
49 |
54 |
55 |
56 |
57 |
61 |
62 |
67 |
68 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48dp
4 |
5 | 1dip
6 | 2dip
7 | 3dip
8 | 4dip
9 | 5dip
10 | 6dip
11 | 7dip
12 | 8dip
13 | 9dip
14 | 10dip
15 | 11dip
16 | 12dip
17 | 13dip
18 | 14dip
19 | 15dip
20 | 16dip
21 | 17dip
22 | 18dip
23 | 19dip
24 | 20dip
25 | 21dip
26 | 22dip
27 | 23dip
28 | 24dip
29 | 25dip
30 | 26dip
31 | 27dip
32 | 28dip
33 | 29dip
34 | 30dip
35 | 31dip
36 | 32dip
37 | 33dip
38 | 34dip
39 | 35dip
40 | 36dip
41 | 37dip
42 | 38dip
43 | 39dip
44 | 40dip
45 | 41dip
46 | 42dip
47 | 43dip
48 | 44dip
49 | 45dip
50 | 46dip
51 | 47dip
52 | 48dip
53 | 49dip
54 | 50dip
55 | 56dip
56 | 64dip
57 | 72dip
58 | 128dip
59 | 256dip
60 | 512dip
61 | 1024dip
62 |
63 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | CameraMask
3 |
4 | \n1、fix bugs
5 | \n2、optimize CameraLensView, add attrs:
6 | \nclvCameraLensWidthWeight:相机镜头宽度比重,例如:{1.5,4}
7 | \nclvCameraLensHeightWeight:相机镜头高度比重,例如:`{5,2}
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/test/java/jsc/exam/com/cameramask/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package jsc.exam.com.cameramask;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.user_org = 'justinquote'
5 | ext.min_sdk_veriosn = 19
6 | ext.sdk_veriosn = 28
7 | ext.component_version = '28.0.0'
8 | ext.version_code = 6
9 | ext.version_name = '0.3.0'
10 |
11 | repositories {
12 | google()
13 | jcenter()
14 | }
15 | dependencies {
16 | classpath 'com.android.tools.build:gradle:3.2.1'
17 | classpath 'com.novoda:bintray-release:0.9'
18 |
19 | // NOTE: Do not place your application dependencies here; they belong
20 | // in the individual module build.gradle files
21 | }
22 | }
23 |
24 | allprojects {
25 | repositories {
26 | google()
27 | jcenter()
28 | }
29 |
30 | tasks.withType(Javadoc) {
31 | options{
32 | encoding "UTF-8"
33 | charSet 'UTF-8'
34 | links "http://docs.oracle.com/javase/8/docs/api"
35 | }
36 | }
37 | }
38 |
39 | task clean(type: Delete) {
40 | delete rootProject.buildDir
41 | }
42 |
--------------------------------------------------------------------------------
/cameraMaskLibrary/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/cameraMaskLibrary/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 |
4 | android {
5 | compileSdkVersion sdk_veriosn
6 |
7 | defaultConfig {
8 | minSdkVersion min_sdk_veriosn
9 | targetSdkVersion sdk_veriosn
10 | versionCode version_code
11 | versionName version_name
12 |
13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14 |
15 | }
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 |
24 | }
25 |
26 | publish {
27 | userOrg = "$user_org"
28 | repoName = 'maven'
29 | groupId = 'jsc.kit.cameramask'
30 | artifactId = 'camera-mask'
31 | publishVersion = "$version_name"
32 | desc = 'a camera mask library'
33 | website = 'https://github.com/JustinRoom/CameraMaskDemo'
34 | }
35 |
36 | dependencies {
37 | implementation fileTree(dir: 'libs', include: ['*.jar'])
38 |
39 | implementation 'com.android.support:appcompat-v7:28.0.0'
40 | testImplementation 'junit:junit:4.12'
41 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
42 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
43 | }
44 |
--------------------------------------------------------------------------------
/cameraMaskLibrary/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/cameraMaskLibrary/src/androidTest/java/jsc/kit/cameramask/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package jsc.kit.cameramask;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("jsc.kit.wheel.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/cameraMaskLibrary/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/cameraMaskLibrary/src/main/java/jsc/kit/cameramask/CameraScannerMaskView.java:
--------------------------------------------------------------------------------
1 | package jsc.kit.cameramask;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Rect;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.util.AttributeSet;
9 | import android.util.Log;
10 | import android.view.ViewGroup;
11 | import android.widget.FrameLayout;
12 |
13 | /**
14 | *
Email:1006368252@qq.com
15 | *
QQ:1006368252
16 | *
https://github.com/JustinRoom/CameraMaskDemo
17 | *
18 | * @author jiangshicheng
19 | */
20 | public class CameraScannerMaskView extends FrameLayout {
21 |
22 | private final String TAG = "CameraScannerMas";
23 | private ScannerBarView scannerBarView;
24 | private CameraLensView cameraLensView;
25 |
26 | public CameraScannerMaskView(@NonNull Context context) {
27 | this(context, null);
28 | }
29 |
30 | public CameraScannerMaskView(@NonNull Context context, @Nullable AttributeSet attrs) {
31 | this(context, attrs, 0);
32 | }
33 |
34 | public CameraScannerMaskView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
35 | super(context, attrs, defStyleAttr);
36 | cameraLensView = new CameraLensView(context);
37 | cameraLensView.init(context, attrs, defStyleAttr);
38 | scannerBarView = new ScannerBarView(context);
39 | scannerBarView.init(context, attrs, defStyleAttr);
40 | addView(cameraLensView, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
41 | addView(scannerBarView, new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
42 | }
43 |
44 | @Override
45 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
46 | measureChildren(widthMeasureSpec, heightMeasureSpec);
47 | reLocationScannerBarView(cameraLensView.getCameraLensRect());
48 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
49 | }
50 |
51 | private void reLocationScannerBarView(@NonNull Rect rect){
52 | ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) scannerBarView.getLayoutParams();
53 | params.width = rect.width();
54 | params.height = rect.height();
55 | params.leftMargin = rect.left;
56 | params.topMargin = rect.top;
57 | scannerBarView.setLayoutParams(params);
58 | }
59 |
60 | public void start() {
61 | scannerBarView.start();
62 | }
63 |
64 | public void pause() {
65 | scannerBarView.pause();
66 | }
67 |
68 | public void resume() {
69 | scannerBarView.resume();
70 | }
71 |
72 | public void stop() {
73 | scannerBarView.stop();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/cameraMaskLibrary/src/main/java/jsc/kit/cameramask/ScannerBarView.java:
--------------------------------------------------------------------------------
1 | package jsc.kit.cameramask;
2 |
3 | import android.animation.ObjectAnimator;
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Bitmap;
7 | import android.support.annotation.DrawableRes;
8 | import android.support.annotation.NonNull;
9 | import android.support.annotation.Nullable;
10 | import android.util.AttributeSet;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.view.animation.Animation;
14 | import android.view.animation.LinearInterpolator;
15 | import android.widget.ImageView;
16 | import android.widget.LinearLayout;
17 |
18 | /**
19 | * ScannerBarView
20 | *
Email:1006368252@qq.com
21 | *
QQ:1006368252
22 | *
https://github.com/JustinRoom/CameraMaskDemo
23 | *
24 | * @author jiangshicheng
25 | */
26 | public class ScannerBarView extends ViewGroup {
27 |
28 | private ImageView scannerBar;
29 | private ObjectAnimator animator = null;
30 |
31 | public ScannerBarView(Context context) {
32 | super(context);
33 | initView(context);
34 | init(context, null, 0);
35 | }
36 |
37 | public ScannerBarView(Context context, AttributeSet attrs) {
38 | super(context, attrs);
39 | initView(context);
40 | init(context, attrs, 0);
41 | }
42 |
43 | public ScannerBarView(Context context, AttributeSet attrs, int defStyleAttr) {
44 | super(context, attrs, defStyleAttr);
45 | initView(context);
46 | init(context, attrs, defStyleAttr);
47 | }
48 |
49 | private void initView(Context context){
50 | scannerBar = new ImageView(context);
51 | scannerBar.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
52 | addView(scannerBar, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
53 | }
54 |
55 | public void init(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
56 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ScannerBarView, defStyleAttr, 0);
57 | scannerBar.setImageResource(a.getResourceId(R.styleable.ScannerBarView_sbvSrc, R.drawable.camera_mask_scanner_bar));
58 | a.recycle();
59 | }
60 |
61 | @Override
62 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
63 | measureChildren(widthMeasureSpec, heightMeasureSpec);
64 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
65 | }
66 |
67 | @Override
68 | protected void onLayout(boolean changed, int l, int t, int r, int b) {
69 | if (getChildCount() > 0) {
70 | for (int i = 0; i < getChildCount(); i++) {
71 | View child = getChildAt(i);
72 | child.layout(0, 0 - child.getMeasuredHeight(), child.getMeasuredWidth(), 0);
73 | }
74 | }
75 | }
76 |
77 | public void setScannerBarImageResource(@DrawableRes int drawable) {
78 | scannerBar.setImageResource(drawable);
79 | executeRequestLayout();
80 | }
81 |
82 | public void setScannerBarImageBitmap(Bitmap bitmap) {
83 | scannerBar.setImageBitmap(bitmap);
84 | executeRequestLayout();
85 | }
86 |
87 | public void start() {
88 | if (animator == null) {
89 | animator = ObjectAnimator.ofFloat(scannerBar, View.TRANSLATION_Y, 0, getHeight() + scannerBar.getHeight());
90 | animator.setInterpolator(new LinearInterpolator());
91 | animator.setDuration(2_000);
92 | animator.setRepeatCount(Animation.INFINITE);
93 | animator.start();
94 | }
95 | }
96 |
97 | public void pause() {
98 | if (animator != null && animator.isRunning())
99 | animator.pause();
100 | }
101 |
102 | public void resume() {
103 | if (animator != null && animator.isPaused())
104 | animator.resume();
105 | }
106 |
107 | public void stop() {
108 | scannerBar.setTranslationY(0);
109 | if (animator != null && animator.isStarted()) {
110 | animator.cancel();
111 | animator = null;
112 | }
113 | }
114 |
115 | public boolean isRunning() {
116 | return animator != null && animator.isRunning();
117 | }
118 |
119 | private void executeRequestLayout() {
120 | boolean needRestart = isRunning();
121 | stop();
122 | requestLayout();
123 | if (needRestart)
124 | start();
125 | }
126 |
127 | @Override
128 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
129 | executeRequestLayout();
130 | }
131 |
132 | @Override
133 | protected void onDetachedFromWindow() {
134 | stop();
135 | super.onDetachedFromWindow();
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/cameraMaskLibrary/src/main/res/drawable/camera_mask_scanner_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/cameraMaskLibrary/src/main/res/drawable/camera_mask_scanner_bar.png
--------------------------------------------------------------------------------
/cameraMaskLibrary/src/main/res/drawable/camera_mask_scanner_line.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/cameraMaskLibrary/src/main/res/drawable/camera_mask_scanner_line.png
--------------------------------------------------------------------------------
/cameraMaskLibrary/src/main/res/values/camera_mask_attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/cameraMaskLibrary/src/test/java/jsc/kit/cameramask/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package jsc.kit.cameramask;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/output/CameraMaskDemo.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/CameraMaskDemo.apk
--------------------------------------------------------------------------------
/output/output.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "outputType": {
4 | "type": "APK"
5 | },
6 | "apkInfo": {
7 | "type": "MAIN",
8 | "splits": [],
9 | "versionCode": 6,
10 | "versionName": "0.3.0",
11 | "enabled": true,
12 | "outputFile": "CameraMaskDemo.apk",
13 | "fullName": "release",
14 | "baseName": "release",
15 | "content": "\n1、fix bugsn2、optimize CameraLensView, add attrs:\nclvCameraLensWidthWeight:相机镜头宽度比重,例如:{1.5,4}\nclvCameraLensHeightWeight:相机镜头高度比重,例如:`{5,2}"
16 | },
17 | "path": "CameraMaskDemo.apk",
18 | "properties": {}
19 | }
20 | ]
--------------------------------------------------------------------------------
/output/shots/camera_lens_view_bitmap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/camera_lens_view_bitmap.png
--------------------------------------------------------------------------------
/output/shots/camera_lens_view_bitmap_s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/camera_lens_view_bitmap_s.png
--------------------------------------------------------------------------------
/output/shots/camera_lens_view_circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/camera_lens_view_circle.png
--------------------------------------------------------------------------------
/output/shots/camera_lens_view_circle_s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/camera_lens_view_circle_s.png
--------------------------------------------------------------------------------
/output/shots/camera_lens_view_pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/camera_lens_view_pic.png
--------------------------------------------------------------------------------
/output/shots/camera_lens_view_pic_s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/camera_lens_view_pic_s.png
--------------------------------------------------------------------------------
/output/shots/camera_lens_view_square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/camera_lens_view_square.png
--------------------------------------------------------------------------------
/output/shots/camera_lens_view_square_s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/camera_lens_view_square_s.png
--------------------------------------------------------------------------------
/output/shots/camera_scanner_mask_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/camera_scanner_mask_view.png
--------------------------------------------------------------------------------
/output/shots/camera_scanner_mask_view_s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/camera_scanner_mask_view_s.png
--------------------------------------------------------------------------------
/output/shots/scanner_bar_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/scanner_bar_view.png
--------------------------------------------------------------------------------
/output/shots/scanner_bar_view_s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustinRoom/CameraMaskDemo/f9fa5ca8346c4f8412a494239e0a7c39dfd5742f/output/shots/scanner_bar_view_s.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':cameraMaskLibrary'
2 |
--------------------------------------------------------------------------------