diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a1e84f2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +/.idea diff --git a/README.md b/README.md new file mode 100644 index 0000000..36e12a8 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# GuideView +新手引导视图,初次打开页面时显示。 + + +*使用图片 + + + ImageView iv = new ImageView(this); + iv.setImageResource(R.drawable.img_new_task_guide); + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + iv.setLayoutParams(params); + +![image](https://github.com/laxian/GuideView/blob/develop/app/snapshot1.jpeg) + +*使用文字 + + TextView iv = new TextView(this); + iv.setText("欢迎使用"); + iv.setTextColor(getResources().getColor(R.color.white)); + +![image](https://github.com/laxian/GuideView/blob/develop/app/snapshot2.jpeg) + +*显示GuideView + + GuideView.Builder + .newInstance(this) // 必须调用 + .setTargetView(view) // 必须调用,设置需要Guide的View + .setCustomTipsView(iv) // 必须调用,设置GuideView,可以使任意View的实例,比如ImageView 或者TextView + .setDirction(GuideView.Direction.LEFT_BOTTOM) // 设置GuideView 相对于TargetView的位置,有八种,不设置则默认在屏幕左上角 + .setBackGround(getResources().getColor(R.color.shadow)) // 设置背景颜色,默认透明 + .setOnclickExit(null) // 设置点击消失,可以传入一个Callback,执行被点击后的操作 + .setRadius(32) // 设置圆形透明区域半径,默认是targetView的显示矩形的半径 + .setCenter(300, 300) // 设置圆心,默认是targetView的中心 + .setOffset(200, 60) // 设置偏移,一般用于微调GuideView的位置 + .showOnce() // 设置首次显示,设置后,显示一次后,不再显示 + .build() // 必须调用,Buider模式,返回GuideView实例 + .show(); // 必须调用,显示GuideView diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..f9b6768 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,28 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion '23.0.2' + defaultConfig { + applicationId "com.laxian.guideview" + minSdkVersion 16 + targetSdkVersion 19 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + productFlavors { + } +} + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + testCompile 'junit:junit:4.12' + compile 'com.android.support:appcompat-v7:23.+' + compile 'com.android.support:design:23.+' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..58bef5c --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in D:\Android\Sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/snapshot1.jpeg b/app/snapshot1.jpeg new file mode 100644 index 0000000..a39f616 Binary files /dev/null and b/app/snapshot1.jpeg differ diff --git a/app/snapshot2.jpeg b/app/snapshot2.jpeg new file mode 100644 index 0000000..43de35e Binary files /dev/null and b/app/snapshot2.jpeg differ diff --git a/app/src/androidTest/java/com/laxian/guideview/ApplicationTest.java b/app/src/androidTest/java/com/laxian/guideview/ApplicationTest.java new file mode 100644 index 0000000..fcfcde3 --- /dev/null +++ b/app/src/androidTest/java/com/laxian/guideview/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.laxian.guideview; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..0fb71dc --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/laxian/guideview/GuideView.java b/app/src/main/java/com/laxian/guideview/GuideView.java new file mode 100644 index 0000000..f50a686 --- /dev/null +++ b/app/src/main/java/com/laxian/guideview/GuideView.java @@ -0,0 +1,554 @@ +package com.laxian.guideview; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.RectF; +import android.util.Log; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.widget.FrameLayout; +import android.widget.RelativeLayout; + +import java.util.List; + +/** + * Created by zhouweixian on 2016/1/23. + */ +public class GuideView extends RelativeLayout implements ViewTreeObserver.OnGlobalLayoutListener { + private final String TAG = getClass().getSimpleName(); + private Context mContent; + private List mViews; + private boolean first = true; + /** + * targetView前缀。SHOW_GUIDE_PREFIX + targetView.getId()作为保存在SP文件的key。 + */ + private static final String SHOW_GUIDE_PREFIX = "show_guide_on_view_"; + /** + * GuideView 偏移量 + */ + private int offsetX, offsetY; + /** + * targetView 的外切圆半径 + */ + private int radius; + /** + * 需要显示提示信息的View + */ + private View targetView; + /** + * 自定义View + */ + private View customGuideView; + /** + * 透明圆形画笔 + */ + private Paint mCirclePaint; + /** + * 背景色画笔 + */ + private Paint mBackgroundPaint; + /** + * targetView是否已测量 + */ + private boolean isMeasured; + /** + * targetView圆心 + */ + private int[] center; + /** + * 绘图层叠模式 + */ + private PorterDuffXfermode porterDuffXfermode; + /** + * 绘制前景bitmap + */ + private Bitmap bitmap; + /** + * 背景色和透明度,格式 #aarrggbb + */ + private int backgroundColor; + /** + * Canvas,绘制bitmap + */ + private Canvas temp; + /** + * 相对于targetView的位置.在target的那个方向 + */ + private Direction direction; + + /** + * 形状 + */ + private MyShape myShape; + /** + * targetView左上角坐标 + */ + private int[] location; + private boolean onClickExit; + private OnClickCallback onclickListener; + private RelativeLayout guideViewLayout; + + public void restoreState() { + Log.v(TAG, "restoreState"); + offsetX = offsetY = 0; + radius = 0; + mCirclePaint = null; + mBackgroundPaint = null; + isMeasured = false; + center = null; + porterDuffXfermode = null; + bitmap = null; + needDraw = true; + // backgroundColor = Color.parseColor("#00000000"); + temp = null; + // direction = null; + + } + + public int[] getLocation() { + return location; + } + + public void setLocation(int[] location) { + this.location = location; + } + + public GuideView(Context context) { + super(context); + this.mContent = context; + init(); + } + + public int getRadius() { + return radius; + } + + public void setRadius(int radius) { + this.radius = radius; + } + + public void setOffsetX(int offsetX) { + this.offsetX = offsetX; + } + + public void setOffsetY(int offsetY) { + this.offsetY = offsetY; + } + + public void setDirection(Direction direction) { + this.direction = direction; + } + + public void setShape(MyShape shape) { + this.myShape = shape; + } + + public void setCustomGuideView(View customGuideView) { + this.customGuideView = customGuideView; + if (!first) { + restoreState(); + } + } + + public void setBgColor(int background_color) { + this.backgroundColor = background_color; + } + + public View getTargetView() { + return targetView; + } + + public void setTargetView(View targetView) { + this.targetView = targetView; + // restoreState(); + if (!first) { + // guideViewLayout.removeAllViews(); + } + } + + private void init() { + } + + public void showOnce() { + if (targetView != null) { + mContent.getSharedPreferences(TAG, Context.MODE_PRIVATE).edit().putBoolean(generateUniqId(targetView), true).commit(); + } + } + + private boolean hasShown() { + if (targetView == null) + return true; + return mContent.getSharedPreferences(TAG, Context.MODE_PRIVATE).getBoolean(generateUniqId(targetView), false); + } + + private String generateUniqId(View v) { + return SHOW_GUIDE_PREFIX + v.getId(); + } + + public int[] getCenter() { + return center; + } + + public void setCenter(int[] center) { + this.center = center; + } + + public void hide() { + Log.v(TAG, "hide"); + if (customGuideView != null) { + targetView.getViewTreeObserver().removeOnGlobalLayoutListener(this); + this.removeAllViews(); + ((FrameLayout) ((Activity) mContent).getWindow().getDecorView()).removeView(this); + restoreState(); + } + } + + public void show() { + Log.v(TAG, "show"); + if (hasShown()) + return; + + if (targetView != null) { + targetView.getViewTreeObserver().addOnGlobalLayoutListener(this); + } + + this.setBackgroundResource(R.color.transparent); + + ((FrameLayout) ((Activity) mContent).getWindow().getDecorView()).addView(this); + first = false; + } + + /** + * 添加提示文字,位置在targetView的下边 + * 在屏幕窗口,添加蒙层,蒙层绘制总背景和透明圆形,圆形下边绘制说明文字 + */ + private void createGuideView() { + Log.v(TAG, "createGuideView"); + + // 添加到蒙层 + // if (guideViewLayout == null) { + // guideViewLayout = new RelativeLayout(mContent); + // } + + // Tips布局参数 + LayoutParams guideViewParams; + guideViewParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + guideViewParams.setMargins(0, center[1] + radius + 10, 0, 0); + + if (customGuideView != null) { + + // LayoutParams guideViewParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + if (direction != null) { + int width = this.getWidth(); + int height = this.getHeight(); + + int left = center[0] - radius; + int right = center[0] + radius; + int top = center[1] - radius; + int bottom = center[1] + radius; + switch (direction) { + case TOP: + this.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL); + guideViewParams.setMargins(offsetX, offsetY - height + top, -offsetX, height - top - offsetY); + break; + case LEFT: + this.setGravity(Gravity.RIGHT); + guideViewParams.setMargins(offsetX - width + left, top + offsetY, width - left - offsetX, -top - offsetY); + break; + case BOTTOM: + this.setGravity(Gravity.CENTER_HORIZONTAL); + guideViewParams.setMargins(offsetX, bottom + offsetY, -offsetX, -bottom - offsetY); + break; + case RIGHT: + guideViewParams.setMargins(right + offsetX, top + offsetY, -right - offsetX, -top - offsetY); + break; + case LEFT_TOP: + this.setGravity(Gravity.RIGHT | Gravity.BOTTOM); + guideViewParams.setMargins(offsetX - width + left, offsetY - height + top, width - left - offsetX, height - top - offsetY); + break; + case LEFT_BOTTOM: + this.setGravity(Gravity.RIGHT); + guideViewParams.setMargins(offsetX - width + left, bottom + offsetY, width - left - offsetX, -bottom - offsetY); + break; + case RIGHT_TOP: + this.setGravity(Gravity.BOTTOM); + guideViewParams.setMargins(right + offsetX, offsetY - height + top, -right - offsetX, height - top - offsetY); + break; + case RIGHT_BOTTOM: + guideViewParams.setMargins(right + offsetX, bottom + offsetY, -right - offsetX, -top - offsetY); + break; + } + } else { + guideViewParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + guideViewParams.setMargins(offsetX, offsetY, -offsetX, -offsetY); + } + + // guideViewLayout.addView(customGuideView); + + this.addView(customGuideView, guideViewParams); + } + } + + /** + * 获得targetView 的宽高,如果未测量,返回{-1, -1} + * + * @return + */ + private int[] getTargetViewSize() { + int[] location = {-1, -1}; + if (isMeasured) { + location[0] = targetView.getWidth(); + location[1] = targetView.getHeight(); + } + return location; + } + + /** + * 获得targetView 的半径 + * + * @return + */ + private int getTargetViewRadius() { + if (isMeasured) { + int[] size = getTargetViewSize(); + int x = size[0]; + int y = size[1]; + + return (int) (Math.sqrt(x * x + y * y) / 2); + } + return -1; + } + + boolean needDraw = true; + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + Log.v(TAG, "onDraw"); + + if (!isMeasured) + return; + + if (targetView == null) + return; + + // if (!needDraw) return; + + drawBackground(canvas); + + } + + private void drawBackground(Canvas canvas) { + Log.v(TAG, "drawBackground"); + needDraw = false; + // 先绘制bitmap,再将bitmap绘制到屏幕 + bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888); + temp = new Canvas(bitmap); + + // 背景画笔 + Paint bgPaint = new Paint(); + if (backgroundColor != 0) + bgPaint.setColor(backgroundColor); + else + bgPaint.setColor(getResources().getColor(R.color.shadow)); + + // 绘制屏幕背景 + temp.drawRect(0, 0, temp.getWidth(), temp.getHeight(), bgPaint); + + // targetView 的透明圆形画笔 + if (mCirclePaint == null) + mCirclePaint = new Paint(); + porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT);// 或者CLEAR + mCirclePaint.setXfermode(porterDuffXfermode); + mCirclePaint.setAntiAlias(true); + + if (myShape != null) { + RectF oval = new RectF(); + switch (myShape) { + case CIRCULAR://圆形 + temp.drawCircle(center[0], center[1], radius, mCirclePaint);//绘制圆形 + break; + case ELLIPSE://椭圆 + //RectF对象 + oval.left = center[0] - 150; //左边 + oval.top = center[1] - 50; //上边 + oval.right = center[0] + 150; //右边 + oval.bottom = center[1] + 50; //下边 + temp.drawOval(oval, mCirclePaint); //绘制椭圆 + break; + case RECTANGULAR://圆角矩形 + //RectF对象 + oval.left = center[0] - 150; //左边 + oval.top = center[1] - 50; //上边 + oval.right = center[0] + 150; //右边 + oval.bottom = center[1] + 50; //下边 + temp.drawRoundRect(oval, radius, radius, mCirclePaint); //绘制圆角矩形 + break; + } + } else { + temp.drawCircle(center[0], center[1], radius, mCirclePaint);//绘制圆形 + } + + // 绘制到屏幕 + canvas.drawBitmap(bitmap, 0, 0, bgPaint); + bitmap.recycle(); + } + + public void setOnClickExit(boolean onClickExit) { + this.onClickExit = onClickExit; + } + + public void setOnclickListener(OnClickCallback onclickListener) { + this.onclickListener = onclickListener; + } + + private void setClickInfo() { + final boolean exit = onClickExit; + setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (onclickListener != null) { + onclickListener.onClickedGuideView(); + } + if (exit) { + hide(); + } + } + }); + } + + @Override + public void onGlobalLayout() { + if (isMeasured) + return; + if (targetView.getHeight() > 0 && targetView.getWidth() > 0) { + isMeasured = true; + } + + // 获取targetView的中心坐标 + if (center == null) { + // 获取右上角坐标 + location = new int[2]; + targetView.getLocationInWindow(location); + center = new int[2]; + // 获取中心坐标 + center[0] = location[0] + targetView.getWidth() / 2; + center[1] = location[1] + targetView.getHeight() / 2; + } + // 获取targetView外切圆半径 + if (radius == 0) { + radius = getTargetViewRadius(); + } + // 添加GuideView + createGuideView(); + } + + /** + * 定义GuideView相对于targetView的方位,共八种。不设置则默认在targetView下方 + */ + enum Direction { + LEFT, TOP, RIGHT, BOTTOM, + LEFT_TOP, LEFT_BOTTOM, + RIGHT_TOP, RIGHT_BOTTOM + } + + /** + * 定义目标控件的形状,共3种。圆形,椭圆,带圆角的矩形(可以设置圆角大小),不设置则默认是圆形 + */ + enum MyShape { + CIRCULAR, ELLIPSE, RECTANGULAR + } + + /** + * GuideView点击Callback + */ + interface OnClickCallback { + void onClickedGuideView(); + } + + public static class Builder { + static GuideView guiderView; + static Builder instance = new Builder(); + Context mContext; + + private Builder() { + } + + public Builder(Context ctx) { + mContext = ctx; + } + + public static Builder newInstance(Context ctx) { + guiderView = new GuideView(ctx); + return instance; + } + + public Builder setTargetView(View target) { + guiderView.setTargetView(target); + return instance; + } + + public Builder setBgColor(int color) { + guiderView.setBgColor(color); + return instance; + } + + public Builder setDirction(Direction dir) { + guiderView.setDirection(dir); + return instance; + } + + public Builder setShape(MyShape shape) { + guiderView.setShape(shape); + return instance; + } + + public Builder setOffset(int x, int y) { + guiderView.setOffsetX(x); + guiderView.setOffsetY(y); + return instance; + } + + public Builder setRadius(int radius) { + guiderView.setRadius(radius); + return instance; + } + + public Builder setCustomGuideView(View view) { + guiderView.setCustomGuideView(view); + return instance; + } + + public Builder setCenter(int X, int Y) { + guiderView.setCenter(new int[]{X, Y}); + return instance; + } + + public Builder showOnce() { + guiderView.showOnce(); + return instance; + } + + public GuideView build() { + guiderView.setClickInfo(); + return guiderView; + } + + public Builder setOnclickExit(boolean onclickExit) { + guiderView.setOnClickExit(onclickExit); + return instance; + } + + public Builder setOnclickListener(final OnClickCallback callback) { + guiderView.setOnclickListener(callback); + return instance; + } + } +} diff --git a/app/src/main/java/com/laxian/guideview/MainActivity.java b/app/src/main/java/com/laxian/guideview/MainActivity.java new file mode 100644 index 0000000..0d4e3da --- /dev/null +++ b/app/src/main/java/com/laxian/guideview/MainActivity.java @@ -0,0 +1,114 @@ +package com.laxian.guideview; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.Gravity; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; + +public class MainActivity extends AppCompatActivity { + + private ImageButton menu; + private Button btnTest; + private Button btnTest2; + private GuideView guideView; + private GuideView guideView3; + private GuideView guideView2; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + menu = (ImageButton) findViewById(R.id.ib_menu); + btnTest = (Button) findViewById(R.id.btn_test); + btnTest2 = (Button) findViewById(R.id.btn_test2); + + } + + private void setGuideView() { + + // 使用图片 + final ImageView iv = new ImageView(this); + iv.setImageResource(R.drawable.img_new_task_guide); + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + iv.setLayoutParams(params); + + // 使用文字 + TextView tv = new TextView(this); + tv.setText("欢迎使用"); + tv.setTextColor(getResources().getColor(R.color.white)); + tv.setTextSize(30); + tv.setGravity(Gravity.CENTER); + + // 使用文字 + final TextView tv2 = new TextView(this); + tv2.setText("欢迎使用2"); + tv2.setTextColor(getResources().getColor(R.color.white)); + tv2.setTextSize(30); + tv2.setGravity(Gravity.CENTER); + + + guideView = GuideView.Builder + .newInstance(this) + .setTargetView(menu)//设置目标 + .setCustomGuideView(iv) + .setDirction(GuideView.Direction.LEFT_BOTTOM) + .setShape(GuideView.MyShape.CIRCULAR) // 设置圆形显示区域, + .setBgColor(getResources().getColor(R.color.shadow)) + .setOnclickListener(new GuideView.OnClickCallback() { + @Override + public void onClickedGuideView() { + guideView.hide(); + guideView2.show(); + } + }) + .build(); + + + guideView2 = GuideView.Builder + .newInstance(this) + .setTargetView(btnTest) + .setCustomGuideView(tv) + .setDirction(GuideView.Direction.LEFT_BOTTOM) + .setShape(GuideView.MyShape.ELLIPSE) // 设置椭圆形显示区域, + .setBgColor(getResources().getColor(R.color.shadow)) + .setOnclickListener(new GuideView.OnClickCallback() { + @Override + public void onClickedGuideView() { + guideView2.hide(); + guideView3.show(); + } + }) + .build(); + + + guideView3 = GuideView.Builder + .newInstance(this) + .setTargetView(btnTest2) + .setCustomGuideView(tv2) + .setDirction(GuideView.Direction.LEFT_BOTTOM) + .setShape(GuideView.MyShape.RECTANGULAR) // 设置矩形显示区域, + .setRadius(80) // 设置圆形或矩形透明区域半径,默认是targetView的显示矩形的半径,如果是矩形,这里是设置矩形圆角大小 + .setBgColor(getResources().getColor(R.color.shadow)) + .setOnclickListener(new GuideView.OnClickCallback() { + @Override + public void onClickedGuideView() { + guideView3.hide(); + guideView.show(); + } + }) + .build(); + guideView.show(); + } + + @Override + protected void onResume() { + super.onResume(); + setGuideView(); + } +} diff --git a/app/src/main/res/drawable-xhdpi/img_new_task_guide.png b/app/src/main/res/drawable-xhdpi/img_new_task_guide.png new file mode 100644 index 0000000..affbdc1 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/img_new_task_guide.png differ diff --git a/app/src/main/res/drawable/ic_menu_moreoverflow.png b/app/src/main/res/drawable/ic_menu_moreoverflow.png new file mode 100644 index 0000000..ee63a9e Binary files /dev/null and b/app/src/main/res/drawable/ic_menu_moreoverflow.png differ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..9964a48 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/app/src/main/res/layout/app_bar.xml b/app/src/main/res/layout/app_bar.xml new file mode 100644 index 0000000..7241b26 --- /dev/null +++ b/app/src/main/res/layout/app_bar.xml @@ -0,0 +1,36 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml new file mode 100644 index 0000000..501bafa --- /dev/null +++ b/app/src/main/res/layout/content_main.xml @@ -0,0 +1,33 @@ + + + +