Java版本待完善
This commit is contained in:
1
pagelayout-java/.gitignore
vendored
Normal file
1
pagelayout-java/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
34
pagelayout-java/build.gradle
Normal file
34
pagelayout-java/build.gradle
Normal file
@@ -0,0 +1,34 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 26
|
||||
|
||||
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 26
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
implementation 'com.android.support:appcompat-v7:26.1.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
}
|
||||
21
pagelayout-java/proguard-rules.pro
vendored
Normal file
21
pagelayout-java/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# 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 *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.hankkin.pagelayout_java;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() throws Exception {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
assertEquals("com.hankkin.pagelayout_java.test", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
2
pagelayout-java/src/main/AndroidManifest.xml
Normal file
2
pagelayout-java/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.hankkin.pagelayout_java" />
|
||||
@@ -0,0 +1,269 @@
|
||||
package com.hankkin.pagelayout_java;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Shader;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
public class BlinkLayout extends LinearLayout {
|
||||
|
||||
private Paint maskPaint;
|
||||
|
||||
private ValueAnimator maskAnimator;
|
||||
|
||||
private Bitmap localAvailableBitmap;
|
||||
private Bitmap localMaskBitmap;
|
||||
|
||||
private Bitmap destinationBitmap;
|
||||
private Bitmap sourceMaskBitmap;
|
||||
private Canvas canvasForRendering;
|
||||
|
||||
private int maskOffsetX;
|
||||
|
||||
private boolean isAnimationStarted;
|
||||
|
||||
private int shimmerAnimationDuration;
|
||||
|
||||
@ColorInt
|
||||
private int shimmerColor;
|
||||
|
||||
public BlinkLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public BlinkLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public BlinkLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
setWillNotDraw(false);
|
||||
|
||||
maskPaint = new Paint();
|
||||
maskPaint.setAntiAlias(true);
|
||||
maskPaint.setDither(true);
|
||||
maskPaint.setFilterBitmap(true);
|
||||
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
||||
|
||||
TypedArray a = context.getTheme().obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.BlinkLayout,
|
||||
0, 0);
|
||||
|
||||
try {
|
||||
shimmerAnimationDuration = a.getInteger(R.styleable.BlinkLayout_blink_animation_duration, 1500);
|
||||
shimmerColor = a.getColor(R.styleable.BlinkLayout_blink_color, ContextCompat.getColor(context, R.color.shimmer_color));
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
resetShimmering();
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
if (!isAnimationStarted || getWidth() <= 0 || getHeight() <= 0) {
|
||||
super.dispatchDraw(canvas);
|
||||
} else {
|
||||
dispatchDrawUsingBitmap(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
public void startShimmerAnimation() {
|
||||
if (isAnimationStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (getWidth() == 0) {
|
||||
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
BlinkLayout.this.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
startShimmerAnimation();
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Animator animator = getShimmerAnimation();
|
||||
animator.start();
|
||||
isAnimationStarted = true;
|
||||
}
|
||||
|
||||
public void stopShimmerAnimation() {
|
||||
resetShimmering();
|
||||
}
|
||||
|
||||
public void setShimmerColor(int shimmerColor) {
|
||||
this.shimmerColor = shimmerColor;
|
||||
|
||||
if (isAnimationStarted) {
|
||||
resetShimmering();
|
||||
startShimmerAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchDrawUsingBitmap(Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
|
||||
localAvailableBitmap = getDestinationBitmap();
|
||||
if (localAvailableBitmap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (canvasForRendering == null) {
|
||||
canvasForRendering = new Canvas(localAvailableBitmap);
|
||||
}
|
||||
|
||||
drawMask(canvasForRendering);
|
||||
canvas.save();
|
||||
canvas.clipRect(maskOffsetX, 0, maskOffsetX + getWidth() / 2, getHeight());
|
||||
canvas.drawBitmap(localAvailableBitmap, 0, 0, null);
|
||||
canvas.restore();
|
||||
|
||||
localAvailableBitmap = null;
|
||||
}
|
||||
|
||||
private void drawMask(Canvas renderCanvas) {
|
||||
localMaskBitmap = getSourceMaskBitmap();
|
||||
if (localMaskBitmap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
renderCanvas.save();
|
||||
renderCanvas.clipRect(maskOffsetX, 0,
|
||||
maskOffsetX + localMaskBitmap.getWidth(),
|
||||
getHeight());
|
||||
|
||||
super.dispatchDraw(renderCanvas);
|
||||
renderCanvas.drawBitmap(localMaskBitmap, maskOffsetX, 0, maskPaint);
|
||||
|
||||
renderCanvas.restore();
|
||||
|
||||
localMaskBitmap = null;
|
||||
}
|
||||
|
||||
private void resetShimmering() {
|
||||
if (maskAnimator != null) {
|
||||
maskAnimator.end();
|
||||
maskAnimator.removeAllUpdateListeners();
|
||||
}
|
||||
|
||||
maskAnimator = null;
|
||||
isAnimationStarted = false;
|
||||
|
||||
releaseBitMaps();
|
||||
}
|
||||
|
||||
private void releaseBitMaps() {
|
||||
if (sourceMaskBitmap != null) {
|
||||
sourceMaskBitmap.recycle();
|
||||
sourceMaskBitmap = null;
|
||||
}
|
||||
|
||||
if (destinationBitmap != null) {
|
||||
destinationBitmap.recycle();
|
||||
destinationBitmap = null;
|
||||
}
|
||||
|
||||
canvasForRendering = null;
|
||||
}
|
||||
|
||||
private Bitmap getDestinationBitmap() {
|
||||
if (destinationBitmap == null) {
|
||||
destinationBitmap = createBitmap(getWidth(), getHeight());
|
||||
}
|
||||
|
||||
return destinationBitmap;
|
||||
}
|
||||
|
||||
private Bitmap getSourceMaskBitmap() {
|
||||
if (sourceMaskBitmap != null) {
|
||||
return sourceMaskBitmap;
|
||||
}
|
||||
|
||||
int width = getWidth() / 2;
|
||||
int height = getHeight();
|
||||
|
||||
sourceMaskBitmap = createBitmap(width, height);
|
||||
Canvas canvas = new Canvas(sourceMaskBitmap);
|
||||
|
||||
LinearGradient gradient = new LinearGradient(
|
||||
0, 0,
|
||||
width, 0,
|
||||
new int[]{Color.TRANSPARENT, shimmerColor, shimmerColor, Color.TRANSPARENT},
|
||||
new float[]{0.25F, 0.5F, 0.5F, 0.75F},
|
||||
Shader.TileMode.CLAMP);
|
||||
|
||||
canvas.rotate(20, width / 2, height / 2);
|
||||
|
||||
Paint paint = new Paint();
|
||||
paint.setShader(gradient);
|
||||
int padding = (int) (Math.sqrt(2) * Math.max(width, height)) / 2;
|
||||
canvas.drawRect(0, -padding, width, height + padding, paint);
|
||||
|
||||
return sourceMaskBitmap;
|
||||
}
|
||||
|
||||
private Animator getShimmerAnimation() {
|
||||
if (maskAnimator != null) {
|
||||
return maskAnimator;
|
||||
}
|
||||
|
||||
final int animationToX = getWidth();
|
||||
final int animationFromX = -animationToX;
|
||||
final int shimmerBitmapWidth = getWidth() / 2;
|
||||
final int shimmerAnimationFullLength = animationToX - animationFromX;
|
||||
|
||||
maskAnimator = ValueAnimator.ofFloat(0.0F, 1.0F);
|
||||
maskAnimator.setDuration(shimmerAnimationDuration);
|
||||
maskAnimator.setRepeatCount(ObjectAnimator.INFINITE);
|
||||
|
||||
final float[] value = new float[1];
|
||||
maskAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
value[0] = (Float) animation.getAnimatedValue();
|
||||
maskOffsetX = ((int) (animationFromX + shimmerAnimationFullLength * value[0]));
|
||||
|
||||
if (maskOffsetX + shimmerBitmapWidth >= 0) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return maskAnimator;
|
||||
}
|
||||
|
||||
private Bitmap createBitmap(int width, int height) {
|
||||
try {
|
||||
return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
} catch (OutOfMemoryError e) {
|
||||
System.gc();
|
||||
return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.hankkin.pagelayout_java;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
||||
/**
|
||||
* Created by ${Hankkin} on 2018/10/12.
|
||||
*/
|
||||
|
||||
public class PageLayout extends FrameLayout {
|
||||
|
||||
enum State{
|
||||
EMPTY_TYPE,
|
||||
LOADING_TYPE,
|
||||
ERROR_TYPE,
|
||||
CONTENT_TYPE,
|
||||
CUSTOM_TYPE
|
||||
}
|
||||
|
||||
private View mLoading;
|
||||
private View mEmpty;
|
||||
private View mError;
|
||||
private View mContent;
|
||||
private View mCustom;
|
||||
private Context mContext;
|
||||
private BlinkLayout mBlinkLayout;
|
||||
private State mCurrentState;
|
||||
|
||||
public PageLayout(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public PageLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public PageLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
private void showView(final State state){
|
||||
if (Looper.myLooper() == Looper.getMainLooper()){
|
||||
changeView(state);
|
||||
}
|
||||
else {
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
changeView(state);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void changeView(State state){
|
||||
mCurrentState = state;
|
||||
switch (state){
|
||||
case LOADING_TYPE:
|
||||
mLoading.setVisibility(VISIBLE);
|
||||
break;
|
||||
case EMPTY_TYPE:
|
||||
mEmpty.setVisibility(VISIBLE);
|
||||
break;
|
||||
case ERROR_TYPE:
|
||||
mError.setVisibility(VISIBLE);
|
||||
break;
|
||||
case CUSTOM_TYPE:
|
||||
mCustom.setVisibility(VISIBLE);
|
||||
break;
|
||||
case CONTENT_TYPE:
|
||||
mContent.setVisibility(VISIBLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void showLoading(){
|
||||
showView(State.LOADING_TYPE);
|
||||
if (mBlinkLayout != null){
|
||||
mBlinkLayout.startShimmerAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
public void showError(){
|
||||
showView(State.ERROR_TYPE);
|
||||
}
|
||||
|
||||
public void showEmpty(){
|
||||
showView(State.EMPTY_TYPE);
|
||||
}
|
||||
|
||||
public void hide(){
|
||||
showView(State.CONTENT_TYPE);
|
||||
if (mBlinkLayout!= null){
|
||||
mBlinkLayout.stopShimmerAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
public void showCustom(){
|
||||
showView(State.CUSTOM_TYPE);
|
||||
}
|
||||
|
||||
class Builder{
|
||||
private PageLayout mPageLayout;
|
||||
private LayoutInflater mInflater;
|
||||
private Context mContext;
|
||||
private TextView mTvEmpty;
|
||||
private TextView mTvError;
|
||||
private TextView mTvErrorRetry;
|
||||
private TextView mTvLoading;
|
||||
private TextView mTvLoadingBlink;
|
||||
private BlinkLayout mBlinkLayout;
|
||||
private OnRetryClickListener mOnRetryClickListener;
|
||||
|
||||
public Builder(Context context) {
|
||||
mContext = context;
|
||||
this.mPageLayout = new PageLayout(mContext);
|
||||
this.mInflater = LayoutInflater.from(mContext);
|
||||
}
|
||||
|
||||
private void initDefault(){
|
||||
if (mPageLayout.mEmpty == null){
|
||||
setDefaultEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setDefaultEmpty(){
|
||||
mPageLayout.mEmpty = mInflater.inflate(R.layout.layout_empty, mPageLayout, false);
|
||||
mTvEmpty = mPageLayout.mEmpty.findViewById(R.id.tv_page_empty);
|
||||
mPageLayout.mEmpty.setVisibility(GONE);
|
||||
mPageLayout.addView(mPageLayout.mEmpty);
|
||||
}
|
||||
|
||||
private void setDefaultError()
|
||||
}
|
||||
|
||||
interface OnRetryClickListener{
|
||||
void onRetry();
|
||||
}
|
||||
}
|
||||
BIN
pagelayout-java/src/main/res/drawable/pic_empty.png
Normal file
BIN
pagelayout-java/src/main/res/drawable/pic_empty.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
BIN
pagelayout-java/src/main/res/drawable/pic_error.png
Normal file
BIN
pagelayout-java/src/main/res/drawable/pic_error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
16
pagelayout-java/src/main/res/layout/layout_empty.xml
Normal file
16
pagelayout-java/src/main/res/layout/layout_empty.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
android:gravity="center"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:drawableTop="@drawable/pic_empty"
|
||||
android:text="@string/page_empty"
|
||||
android:id="@+id/tv_page_empty"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
29
pagelayout-java/src/main/res/layout/layout_error.xml
Normal file
29
pagelayout-java/src/main/res/layout/layout_error.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.hankkin.pagelayout.BlinkLayout
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:drawableTop="@drawable/pic_error"
|
||||
android:gravity="center"
|
||||
android:text="@string/page_error"
|
||||
android:id="@+id/tv_page_error"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:textColor="@color/colorPrimary"
|
||||
android:layout_marginTop="10dp"
|
||||
android:textSize="13sp"
|
||||
android:gravity="center"
|
||||
android:text="@string/page_error_retry"
|
||||
android:id="@+id/tv_page_error_retry"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</com.hankkin.pagelayout.BlinkLayout>
|
||||
19
pagelayout-java/src/main/res/layout/layout_loading.xml
Normal file
19
pagelayout-java/src/main/res/layout/layout_loading.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.hankkin.pagelayout.BlinkLayout
|
||||
android:id="@+id/blinklayout"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<TextView
|
||||
android:text="PageLaout"
|
||||
android:textStyle="bold"
|
||||
android:textSize="25sp"
|
||||
android:textColor="@color/blink_color"
|
||||
android:id="@+id/tv_page_loading_blink"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</com.hankkin.pagelayout.BlinkLayout>
|
||||
9
pagelayout-java/src/main/res/values/colors.xml
Normal file
9
pagelayout-java/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#ff662c</color>
|
||||
<color name="colorPrimaryDark">#ff662c</color>
|
||||
<color name="colorAccent">#ff662c</color>
|
||||
<color name="blink_color">#b1b1b1</color>
|
||||
<color name="shimmer_color">#a2878787</color>
|
||||
|
||||
</resources>
|
||||
6
pagelayout-java/src/main/res/values/strings.xml
Normal file
6
pagelayout-java/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<string name="app_name">EmptyPage</string>
|
||||
<string name="page_error">网络开小差了</string>
|
||||
<string name="page_error_retry">点击重试</string>
|
||||
<string name="page_empty">暂无新数据</string>
|
||||
</resources>
|
||||
16
pagelayout-java/src/main/res/values/styles.xml
Normal file
16
pagelayout-java/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<declare-styleable name="BlinkLayout">
|
||||
<attr name="blink_color" format="color|reference"/>
|
||||
<attr name="blink_animation_duration" format="integer|reference"/>
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hankkin.pagelayout_java;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() throws Exception {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user