Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
B
Browser White
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wanglei
Browser White
Commits
163e8389
Commit
163e8389
authored
Sep 04, 2024
by
leichao.gao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add label
parent
0f1ded04
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
2324 additions
and
1 deletion
+2324
-1
build.gradle.kts
app/build.gradle.kts
+4
-1
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+6
-0
LabelActivity.java
.../main/java/com/base/browserwhite/label/LabelActivity.java
+304
-0
fragConst.java
...java/com/base/browserwhite/label/constance/fragConst.java
+24
-0
mainActivitySimpleOnGestureListener.java
...ite/label/custom/mainActivitySimpleOnGestureListener.java
+98
-0
PercentLayoutHelper.java
...se/browserwhite/label/customview/PercentLayoutHelper.java
+965
-0
PercentRelativeLayout.java
.../browserwhite/label/customview/PercentRelativeLayout.java
+132
-0
verticalViewPager.java
...base/browserwhite/label/customview/verticalViewPager.java
+30
-0
baseEvent.java
...ain/java/com/base/browserwhite/label/event/baseEvent.java
+8
-0
delThisFrag.java
...n/java/com/base/browserwhite/label/event/delThisFrag.java
+9
-0
deleteFragEvent.java
...va/com/base/browserwhite/label/event/deleteFragEvent.java
+23
-0
fragEvent.java
...ain/java/com/base/browserwhite/label/event/fragEvent.java
+24
-0
showDelImg.java
...in/java/com/base/browserwhite/label/event/showDelImg.java
+23
-0
slideEvent.java
...in/java/com/base/browserwhite/label/event/slideEvent.java
+34
-0
zoomEvent.java
...ain/java/com/base/browserwhite/label/event/zoomEvent.java
+23
-0
baseFrag.java
...n/java/com/base/browserwhite/label/fragment/baseFrag.java
+30
-0
fragAdapter.java
...ava/com/base/browserwhite/label/fragment/fragAdapter.java
+86
-0
mainFrag.java
...n/java/com/base/browserwhite/label/fragment/mainFrag.java
+233
-0
MainActivity.kt
...in/java/com/base/browserwhite/ui/activity/MainActivity.kt
+3
-0
fragment_label.xml
app/src/main/res/layout/fragment_label.xml
+66
-0
label.xml
app/src/main/res/layout/label.xml
+172
-0
attrs.xml
app/src/main/res/values/attrs.xml
+27
-0
No files found.
app/build.gradle.kts
View file @
163e8389
...
@@ -139,7 +139,10 @@ dependencies {
...
@@ -139,7 +139,10 @@ dependencies {
// RxJava 3.1.3
// RxJava 3.1.3
implementation
(
"io.reactivex.rxjava3:rxjava:3.1.3"
)
implementation
(
"io.reactivex.rxjava3:rxjava:3.1.3"
)
implementation
(
"io.reactivex.rxjava3:rxandroid:3.0.0"
)
implementation
(
"io.reactivex.rxjava3:rxandroid:3.0.0"
)
//facebook
//facebook
implementation
(
"org.greenrobot:eventbus:3.0.0"
)
implementation
(
"com.facebook.android:facebook-android-sdk:[8,9)"
)
implementation
(
"com.facebook.android:facebook-android-sdk:[8,9)"
)
// implementation("com.zhy:percent-support-extends:1.1.1")
}
}
\ No newline at end of file
app/src/main/AndroidManifest.xml
View file @
163e8389
...
@@ -98,6 +98,12 @@
...
@@ -98,6 +98,12 @@
android:launchMode=
"singleTop"
android:launchMode=
"singleTop"
android:screenOrientation=
"portrait"
android:screenOrientation=
"portrait"
tools:ignore=
"DiscouragedApi,LockedOrientationActivity"
/>
tools:ignore=
"DiscouragedApi,LockedOrientationActivity"
/>
<activity
android:name=
".label.LabelActivity"
android:exported=
"false"
android:launchMode=
"singleTop"
android:screenOrientation=
"portrait"
tools:ignore=
"DiscouragedApi,LockedOrientationActivity"
/>
<activity
<activity
android:name=
".ui.activity.webbrowser.WebBrowserActivity"
android:name=
".ui.activity.webbrowser.WebBrowserActivity"
android:exported=
"true"
android:exported=
"true"
...
...
app/src/main/java/com/base/browserwhite/label/LabelActivity.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
;
import
android.animation.ObjectAnimator
;
import
android.animation.PropertyValuesHolder
;
import
android.os.Handler
;
import
android.os.Bundle
;
import
android.util.DisplayMetrics
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.ImageView
;
import
android.widget.LinearLayout
;
import
android.widget.RelativeLayout
;
import
android.widget.TextView
;
import
com.base.browserwhite.R
;
import
com.base.browserwhite.label.custom.mainActivitySimpleOnGestureListener
;
import
com.base.browserwhite.label.event.delThisFrag
;
import
com.base.browserwhite.label.event.deleteFragEvent
;
import
com.base.browserwhite.label.event.showDelImg
;
import
com.base.browserwhite.label.constance.fragConst
;
import
com.base.browserwhite.label.customview.PercentRelativeLayout
;
import
com.base.browserwhite.label.customview.verticalViewPager
;
import
com.base.browserwhite.label.event.baseEvent
;
import
com.base.browserwhite.label.event.fragEvent
;
import
com.base.browserwhite.label.event.slideEvent
;
import
com.base.browserwhite.label.event.zoomEvent
;
import
com.base.browserwhite.label.fragment.fragAdapter
;
import
com.base.browserwhite.label.fragment.mainFrag
;
import
static
android
.
widget
.
RelativeLayout
.*;
import
androidx.core.view.GestureDetectorCompat
;
import
androidx.fragment.app.FragmentActivity
;
import
org.greenrobot.eventbus.EventBus
;
import
org.greenrobot.eventbus.Subscribe
;
public
class
LabelActivity
extends
FragmentActivity
{
private
verticalViewPager
mViewPager
;
private
fragAdapter
fragPagerAdapter
;
private
TextView
pagebt
;
private
ImageView
leftbt
,
rightbt
,
setbt
,
homebt
,
delfrag
,
addnewpage
,
returnmain
;
private
LinearLayout
llayoutviewpage
,
pagebarlt
,
mainbarlt
;
private
DisplayMetrics
dm2
;
private
GestureDetectorCompat
mDetector
;
private
PercentRelativeLayout
mainrootrl
;
private
mainActivitySimpleOnGestureListener
mainSimpleOnGestureListener
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
label
);
for
(
int
i
=
0
;
i
<
fragConst
.
init_page_count
;
i
++)
{
mainFrag
tmp
=
new
mainFrag
();
fragConst
.
fraglist
.
add
(
tmp
);
fragConst
.
fraghashcode
.
add
(
String
.
valueOf
(
tmp
.
hashCode
()));
}
mViewPager
=
(
verticalViewPager
)
findViewById
(
R
.
id
.
mainviewpage
);
fragPagerAdapter
=
new
fragAdapter
(
this
,
getSupportFragmentManager
());
mViewPager
.
setAdapter
(
fragPagerAdapter
);
mViewPager
.
setOffscreenPageLimit
(
3
);
// EventBus.getDefault().register(this);
mainSimpleOnGestureListener
=
new
mainActivitySimpleOnGestureListener
();
mDetector
=
new
GestureDetectorCompat
(
this
,
mainSimpleOnGestureListener
);
mainrootrl
=
(
PercentRelativeLayout
)
findViewById
(
R
.
id
.
mainrootrl
);
viewInit
();
}
private
void
viewInit
()
{
leftbt
=
(
ImageView
)
findViewById
(
R
.
id
.
leftbt
);
rightbt
=
(
ImageView
)
findViewById
(
R
.
id
.
rightbt
);
setbt
=
(
ImageView
)
findViewById
(
R
.
id
.
setbt
);
pagebt
=
(
TextView
)
findViewById
(
R
.
id
.
pagebt
);
homebt
=
(
ImageView
)
findViewById
(
R
.
id
.
homebt
);
delfrag
=
(
ImageView
)
findViewById
(
R
.
id
.
delfrag
);
addnewpage
=
(
ImageView
)
findViewById
(
R
.
id
.
addnewpage
);
returnmain
=
(
ImageView
)
findViewById
(
R
.
id
.
returnmain
);
leftbt
.
setOnClickListener
((
View
v
)
->
{
bthander
(
v
.
getId
());
});
rightbt
.
setOnClickListener
((
View
v
)
->
{
bthander
(
v
.
getId
());
});
setbt
.
setOnClickListener
((
View
v
)
->
{
bthander
(
v
.
getId
());
});
pagebt
.
setOnClickListener
((
View
v
)
->
{
bthander
(
v
.
getId
());
});
homebt
.
setOnClickListener
((
View
v
)
->
{
bthander
(
v
.
getId
());
});
addnewpage
.
setOnClickListener
((
View
v
)
->
{
bthander
(
v
.
getId
());
});
returnmain
.
setOnClickListener
((
View
v
)
->
{
bthander
(
v
.
getId
());
});
mainbarlt
=
(
LinearLayout
)
findViewById
(
R
.
id
.
mainbarlt
);
pagebarlt
=
(
LinearLayout
)
findViewById
(
R
.
id
.
pagebarlt
);
llayoutviewpage
=
(
LinearLayout
)
findViewById
(
R
.
id
.
llayoutviewpage
);
dm2
=
getResources
().
getDisplayMetrics
();
mainrootrl
.
setOnTouchListener
((
View
v
,
MotionEvent
event
)
->
{
mDetector
.
onTouchEvent
(
event
);
return
true
;
});
pagebt
.
setText
(
fragConst
.
fraglist
.
size
()
+
""
);
}
public
void
bthander
(
int
id
)
{
if
(
id
==
R
.
id
.
leftbt
)
{
// 处理 leftbt 按钮点击事件
}
else
if
(
id
==
R
.
id
.
rightbt
)
{
// 处理 rightbt 按钮点击事件
}
else
if
(
id
==
R
.
id
.
setbt
)
{
// 处理 setbt 按钮点击事件
}
else
if
(
id
==
R
.
id
.
pagebt
)
{
zoomchange
();
}
else
if
(
id
==
R
.
id
.
homebt
)
{
// removePage(mViewPager.getCurrentItem());
}
else
if
(
id
==
R
.
id
.
addnewpage
)
{
addNewPage
();
}
else
if
(
id
==
R
.
id
.
returnmain
)
{
zoomchange
();
}
}
private
void
addNewPage
()
{
mainFrag
tmp
=
new
mainFrag
();
fragConst
.
fraghashcode
.
add
(
String
.
valueOf
(
tmp
.
hashCode
()));
fragConst
.
fraglist
.
add
(
mViewPager
.
getCurrentItem
()
+
1
,
tmp
);
fragPagerAdapter
.
notifyDataSetChanged
();
mViewPager
.
setCurrentItem
(
mViewPager
.
getCurrentItem
()
+
1
);
Handler
handler
=
new
Handler
();
handler
.
postDelayed
(()
->
{
if
(
dm2
.
widthPixels
-
mViewPager
.
getWidth
()
<
5
)
{
}
else
{
zoomchange
();
}
},
400
);
}
private
void
removePage
(
int
position
)
{
if
(
position
>=
0
&&
position
<
fragConst
.
fraglist
.
size
())
{
if
(
fragConst
.
fraglist
.
size
()
<=
1
)
{
return
;
}
fragConst
.
fraglist
.
remove
(
position
);
fragConst
.
fraghashcode
.
remove
(
position
);
fragPagerAdapter
.
notifyDataSetChanged
();
}
}
private
boolean
currentIsFull
=
true
;
//当前是不是全屏
private
void
zoomchange
()
{
int
thewidth
=
mViewPager
.
getWidth
();
if
(
dm2
.
widthPixels
-
mViewPager
.
getWidth
()
<
5
)
{
mViewPager
.
setPageMargin
(
fragConst
.
page_interval
);
// Logger.v("缩小 " + thewidth);
llayoutviewpage
.
setGravity
(
CENTER_IN_PARENT
);
//缩小
PropertyValuesHolder
pvhX
=
PropertyValuesHolder
.
ofFloat
(
"scaleX"
,
1
f
,
0.8f
);
PropertyValuesHolder
pvhY
=
PropertyValuesHolder
.
ofFloat
(
"scaleY"
,
1
f
,
0.8f
);
ObjectAnimator
scale
=
ObjectAnimator
.
ofPropertyValuesHolder
(
mViewPager
,
pvhX
,
pvhY
);
scale
.
setDuration
(
30
);
scale
.
start
();
RelativeLayout
.
LayoutParams
Rlparam
=
new
RelativeLayout
.
LayoutParams
(
dm2
.
widthPixels
*
8
/
10
,
dm2
.
heightPixels
*
8
/
10
);
Rlparam
.
addRule
(
CENTER_IN_PARENT
);
llayoutviewpage
.
setLayoutParams
(
Rlparam
);
mainSimpleOnGestureListener
.
setViewPagePosition
(
mViewPager
.
getWidth
(),
mViewPager
.
getHeight
());
pagebarlt
.
setVisibility
(
VISIBLE
);
mainbarlt
.
setVisibility
(
INVISIBLE
);
EventBus
.
getDefault
().
post
(
new
zoomEvent
(
false
));
}
else
{
// Logger.v("放大 " + thewidth + " ---- " + dm2.widthPixels);
mViewPager
.
setPageMargin
(
0
);
//放大到原来样子
PropertyValuesHolder
pvhX
=
PropertyValuesHolder
.
ofFloat
(
"scaleX"
,
0.8f
,
1
f
);
PropertyValuesHolder
pvhY
=
PropertyValuesHolder
.
ofFloat
(
"scaleY"
,
0.8f
,
1
f
);
ObjectAnimator
scale
=
ObjectAnimator
.
ofPropertyValuesHolder
(
mViewPager
,
pvhX
,
pvhY
);
scale
.
setDuration
(
30
);
scale
.
start
();
currentIsFull
=
true
;
RelativeLayout
.
LayoutParams
Rlparam2
=
new
RelativeLayout
.
LayoutParams
(
ViewGroup
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
MATCH_PARENT
);
Rlparam2
.
addRule
(
CENTER_IN_PARENT
);
llayoutviewpage
.
setLayoutParams
(
Rlparam2
);
pagebarlt
.
setVisibility
(
INVISIBLE
);
mainbarlt
.
setVisibility
(
VISIBLE
);
pagebt
.
setText
(
fragConst
.
fraglist
.
size
()
+
""
);
EventBus
.
getDefault
().
post
(
new
zoomEvent
(
true
));
}
}
@Subscribe
public
void
onEventMainThread
(
baseEvent
event
)
{
if
(
event
instanceof
fragEvent
)
{
// Toast.makeText(this, " 收到 event 数据 " + ((fragEvent) event).getFragTag(), Toast.LENGTH_SHORT).show();
if
(
dm2
.
widthPixels
-
mViewPager
.
getWidth
()
<
5
)
{
}
else
{
zoomchange
();
}
}
if
(
event
instanceof
slideEvent
)
{
// Toast.makeText(this, " 收到 event 数据 " + ((slideEvent) event).getType()+" "+((slideEvent) event).getDirection(), Toast.LENGTH_SHORT).show();
switch
(((
slideEvent
)
event
).
getType
())
{
case
MotionEvent
.
ACTION_MOVE
:
switch
(((
slideEvent
)
event
).
getDirection
())
{
case
"left"
:
break
;
case
"right"
:
break
;
}
break
;
case
MotionEvent
.
ACTION_DOWN
:
switch
(((
slideEvent
)
event
).
getDirection
())
{
case
"left"
:
int
cItem
=
mViewPager
.
getCurrentItem
();
mViewPager
.
setCurrentItem
(
cItem
>
0
?
cItem
-
1
:
cItem
);
break
;
case
"right"
:
int
rItem
=
mViewPager
.
getCurrentItem
();
mViewPager
.
setCurrentItem
(
rItem
<
fragConst
.
fraglist
.
size
()
-
1
?
rItem
+
1
:
rItem
);
break
;
}
break
;
}
}
if
(
event
instanceof
deleteFragEvent
)
{
int
i
=
0
;
String
Tag
=
((
deleteFragEvent
)
event
).
getFragTag
();
for
(
mainFrag
temp
:
fragConst
.
fraglist
)
{
if
(
temp
.
getFragTag
().
equals
(
Tag
))
{
Handler
dohandler
=
new
Handler
();
final
int
page
=
i
;
dohandler
.
postDelayed
(()
->
{
// Logger.v("删除 page " + page);
removePage
(
page
);
},
80
);
}
i
++;
}
}
if
(
event
instanceof
showDelImg
)
{
if
(((
showDelImg
)
event
).
isShow
())
{
delfrag
.
setVisibility
(
VISIBLE
);
}
else
{
delfrag
.
setVisibility
(
INVISIBLE
);
}
}
if
(
event
instanceof
delThisFrag
)
{
removePage
(
mViewPager
.
getCurrentItem
());
}
}
@Override
protected
void
onDestroy
()
{
super
.
onDestroy
();
EventBus
.
getDefault
().
unregister
(
this
);
fragConst
.
fraglist
.
clear
();
fragConst
.
new_mainfrag_count
=
0
;
//调用次数清0
}
}
app/src/main/java/com/base/browserwhite/label/constance/fragConst.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
constance
;
import
com.base.browserwhite.label.fragment.mainFrag
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* Created by Administrator on 2016/8/20.
*/
public
class
fragConst
{
public
static
List
<
mainFrag
>
fraglist
=
new
ArrayList
<>();
//fraglist和fraghashcode成对出现
public
static
List
<
String
>
fraghashcode
=
new
ArrayList
<>();
//存储对象的hashcode
public
static
int
page_interval
=
40
;
//界面之间的间隔
public
static
int
init_page_count
=
1
;
//初始化的界面个数
public
static
int
new_mainfrag_count
=
0
;
// mainFrag类构造函数被调用的次数
}
app/src/main/java/com/base/browserwhite/label/custom/mainActivitySimpleOnGestureListener.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
custom
;
import
android.view.GestureDetector
;
import
android.view.MotionEvent
;
import
com.base.browserwhite.label.event.slideEvent
;
import
org.greenrobot.eventbus.EventBus
;
/**
* Created by Administrator on 2016/8/23.
*/
public
class
mainActivitySimpleOnGestureListener
extends
GestureDetector
.
SimpleOnGestureListener
{
private
int
mViewpageX
,
mViewpageY
,
mViewpageWidth
,
mViewpageHeight
;
public
void
setViewPagePosition
(
int
mViewpageWidth
,
int
mViewpageHeight
){
this
.
mViewpageWidth
=
mViewpageWidth
*
7
/
10
;
this
.
mViewpageHeight
=
mViewpageHeight
*
7
/
10
;
this
.
mViewpageX
=
(
mViewpageWidth
/
2
)-(
mViewpageWidth
*
7
/
10
/
2
);
this
.
mViewpageY
=
(
mViewpageHeight
/
2
)-(
mViewpageHeight
*
7
/
10
/
2
);;
}
@Override
public
boolean
onFling
(
MotionEvent
e1
,
MotionEvent
e2
,
float
velocityX
,
float
velocityY
)
{
// Logger.v("onFling "+ "x: "+e1.getX() +" y: "+e1.getY() +"x: "+e2.getX() +" y: "+e2.getY() );
JudgeSendEvent
(
"onFling"
,
e1
,
e2
);
return
super
.
onFling
(
e1
,
e2
,
velocityX
,
velocityY
);
}
@Override
public
boolean
onDown
(
MotionEvent
e
)
{
// Logger.v("onDown "+ "x: "+e.getX() +" y: "+e.getY() );
JudgeSendEvent
(
"onDown"
,
e
,
null
);
return
super
.
onDown
(
e
);
}
//判断是否发出事件
private
void
JudgeSendEvent
(
String
action
,
MotionEvent
e1
,
MotionEvent
e2
){
switch
(
action
){
case
"onFling"
:
if
(
e1
.
getX
()<
mViewpageX
&&
e1
.
getY
()>
mViewpageY
&&
e1
.
getY
()<(
mViewpageY
+
mViewpageHeight
)
){
if
(
e2
.
getX
()-
e1
.
getX
()
>
20
){
// Logger.v(" 向右滑动 ");
EventBus
.
getDefault
().
post
(
new
slideEvent
(
MotionEvent
.
ACTION_MOVE
,
"right"
));
// 发送消息
}
else
if
(
e1
.
getX
()-
e2
.
getX
()
>
20
){
// Logger.v(" 向左滑动 ");
EventBus
.
getDefault
().
post
(
new
slideEvent
(
MotionEvent
.
ACTION_MOVE
,
"left"
));
}
}
else
if
(
e1
.
getX
()>(
mViewpageX
+
mViewpageWidth
)&&
e1
.
getY
()>
mViewpageY
&&
e1
.
getY
()<(
mViewpageY
+
mViewpageHeight
)
){
if
(
e2
.
getX
()-
e1
.
getX
()
>
20
){
EventBus
.
getDefault
().
post
(
new
slideEvent
(
MotionEvent
.
ACTION_MOVE
,
"right"
));
// Logger.v(" 向右滑动 ");
}
else
if
(
e1
.
getX
()-
e2
.
getX
()
>
20
){
// Logger.v(" 向左滑动 ");
EventBus
.
getDefault
().
post
(
new
slideEvent
(
MotionEvent
.
ACTION_MOVE
,
"left"
));
}
}
break
;
case
"onDown"
:
// Logger.v( " onDown "+e1.getX()+" "+e1.getY()
// +"\n mViewpageX "+mViewpageX +" mViewpageWidth "+mViewpageWidth
// +"\n mViewpageY "+mViewpageY +" mViewpageWidth "+mViewpageHeight);
if
(
e1
.
getX
()<
mViewpageX
&&
e1
.
getY
()>
mViewpageY
&&
e1
.
getY
()<(
mViewpageY
+
mViewpageHeight
)
){
// Logger.v( " onDown left " );
EventBus
.
getDefault
().
post
(
new
slideEvent
(
MotionEvent
.
ACTION_DOWN
,
"left"
));
}
else
if
(
e1
.
getX
()>(
mViewpageX
+
mViewpageWidth
)&&
e1
.
getY
()>
mViewpageY
&&
e1
.
getY
()<(
mViewpageY
+
mViewpageHeight
)
){
EventBus
.
getDefault
().
post
(
new
slideEvent
(
MotionEvent
.
ACTION_DOWN
,
"right"
));
//Logger.v( " onDown right " );
}
break
;
}
}
}
app/src/main/java/com/base/browserwhite/label/customview/PercentLayoutHelper.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
customview
;
import
android.content.Context
;
import
android.content.res.TypedArray
;
import
android.util.AttributeSet
;
import
android.util.DisplayMetrics
;
import
android.util.Log
;
import
android.util.TypedValue
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.view.WindowManager
;
import
android.widget.TextView
;
import
androidx.annotation.NonNull
;
import
androidx.core.view.MarginLayoutParamsCompat
;
import
androidx.core.view.ViewCompat
;
import
com.base.browserwhite.R
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* Helper for layouts that want to support percentage based dimensions.
* <p/>
* <p>This class collects utility methods that are involved in extracting percentage based dimension
* attributes and applying them to ViewGroup's children. If you would like to implement a layout
* that supports percentage based dimensions, you need to take several steps:
* <p/>
* <ol>
* <li> You need a {@link ViewGroup.LayoutParams} subclass in your ViewGroup that implements
* <li> In your {@code LayoutParams(Context c, AttributeSet attrs)} constructor create an instance
* of {@link PercentLayoutHelper.PercentLayoutInfo} by calling
* {@link PercentLayoutHelper#getPercentLayoutInfo(Context, AttributeSet)}. Return this
* object from {@code public PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo()}
* <li> Override
* with a single line implementation {@code PercentLayoutHelper.fetchWidthAndHeight(this, a,
* widthAttr, heightAttr);}
* <li> In your ViewGroup override {@link ViewGroup#generateLayoutParams(AttributeSet)} to return
* your LayoutParams.
* pattern:
* <pre class="prettyprint">
* protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
* mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec);
* super.onMeasure(widthMeasureSpec, heightMeasureSpec);
* if (mHelper.handleMeasuredStateTooSmall()) {
* super.onMeasure(widthMeasureSpec, heightMeasureSpec);
* }
* }
* </pre>
* implement following pattern:
* <pre class="prettyprint">
* protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
* super.onLayout(changed, left, top, right, bottom);
* mHelper.restoreOriginalParams();
* }
* </pre>
* </ol>
*/
public
class
PercentLayoutHelper
{
private
static
final
String
TAG
=
"PercentLayout"
;
private
final
ViewGroup
mHost
;
private
static
int
mWidthScreen
;
private
static
int
mHeightScreen
;
public
PercentLayoutHelper
(
ViewGroup
host
)
{
mHost
=
host
;
getScreenSize
();
}
private
void
getScreenSize
()
{
WindowManager
wm
=
(
WindowManager
)
mHost
.
getContext
().
getSystemService
(
Context
.
WINDOW_SERVICE
);
DisplayMetrics
outMetrics
=
new
DisplayMetrics
();
wm
.
getDefaultDisplay
().
getMetrics
(
outMetrics
);
mWidthScreen
=
outMetrics
.
widthPixels
;
mHeightScreen
=
outMetrics
.
heightPixels
;
}
/**
* Helper method to be called from override
* that reads layout_width and layout_height attribute values without throwing an exception if
* they aren't present.
*/
public
static
void
fetchWidthAndHeight
(
ViewGroup
.
LayoutParams
params
,
TypedArray
array
,
int
widthAttr
,
int
heightAttr
)
{
params
.
width
=
array
.
getLayoutDimension
(
widthAttr
,
0
);
params
.
height
=
array
.
getLayoutDimension
(
heightAttr
,
0
);
}
/**
* Iterates over children and changes their width and height to one calculated from percentage
* values.
*
* @param widthMeasureSpec Width MeasureSpec of the parent ViewGroup.
* @param heightMeasureSpec Height MeasureSpec of the parent ViewGroup.
*/
public
void
adjustChildren
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
{
Log
.
d
(
TAG
,
"adjustChildren: "
+
mHost
+
" widthMeasureSpec: "
+
View
.
MeasureSpec
.
toString
(
widthMeasureSpec
)
+
" heightMeasureSpec: "
+
View
.
MeasureSpec
.
toString
(
heightMeasureSpec
));
}
int
widthHint
=
View
.
MeasureSpec
.
getSize
(
widthMeasureSpec
);
int
heightHint
=
View
.
MeasureSpec
.
getSize
(
heightMeasureSpec
);
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
Log
.
d
(
TAG
,
"widthHint = "
+
widthHint
+
" , heightHint = "
+
heightHint
);
for
(
int
i
=
0
,
N
=
mHost
.
getChildCount
();
i
<
N
;
i
++)
{
View
view
=
mHost
.
getChildAt
(
i
);
ViewGroup
.
LayoutParams
params
=
view
.
getLayoutParams
();
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
{
Log
.
d
(
TAG
,
"should adjust "
+
view
+
" "
+
params
);
}
if
(
params
instanceof
PercentLayoutParams
)
{
PercentLayoutInfo
info
=
((
PercentLayoutParams
)
params
).
getPercentLayoutInfo
();
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
{
Log
.
d
(
TAG
,
"using "
+
info
);
}
if
(
info
!=
null
)
{
supportTextSize
(
widthHint
,
heightHint
,
view
,
info
);
supportPadding
(
widthHint
,
heightHint
,
view
,
info
);
supportMinOrMaxDimesion
(
widthHint
,
heightHint
,
view
,
info
);
if
(
params
instanceof
ViewGroup
.
MarginLayoutParams
)
{
info
.
fillMarginLayoutParams
((
ViewGroup
.
MarginLayoutParams
)
params
,
widthHint
,
heightHint
);
}
else
{
info
.
fillLayoutParams
(
params
,
widthHint
,
heightHint
);
}
}
}
}
}
private
void
supportPadding
(
int
widthHint
,
int
heightHint
,
View
view
,
PercentLayoutInfo
info
)
{
int
left
=
view
.
getPaddingLeft
(),
right
=
view
.
getPaddingRight
(),
top
=
view
.
getPaddingTop
(),
bottom
=
view
.
getPaddingBottom
();
PercentLayoutInfo
.
PercentVal
percentVal
=
info
.
paddingLeftPercent
;
if
(
percentVal
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
percentVal
.
basemode
);
left
=
(
int
)
(
base
*
percentVal
.
percent
);
}
percentVal
=
info
.
paddingRightPercent
;
if
(
percentVal
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
percentVal
.
basemode
);
right
=
(
int
)
(
base
*
percentVal
.
percent
);
}
percentVal
=
info
.
paddingTopPercent
;
if
(
percentVal
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
percentVal
.
basemode
);
top
=
(
int
)
(
base
*
percentVal
.
percent
);
}
percentVal
=
info
.
paddingBottomPercent
;
if
(
percentVal
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
percentVal
.
basemode
);
bottom
=
(
int
)
(
base
*
percentVal
.
percent
);
}
view
.
setPadding
(
left
,
top
,
right
,
bottom
);
}
private
void
supportMinOrMaxDimesion
(
int
widthHint
,
int
heightHint
,
View
view
,
PercentLayoutInfo
info
)
{
try
{
Class
clazz
=
view
.
getClass
();
invokeMethod
(
"setMaxWidth"
,
widthHint
,
heightHint
,
view
,
clazz
,
info
.
maxWidthPercent
);
invokeMethod
(
"setMaxHeight"
,
widthHint
,
heightHint
,
view
,
clazz
,
info
.
maxHeightPercent
);
invokeMethod
(
"setMinWidth"
,
widthHint
,
heightHint
,
view
,
clazz
,
info
.
minWidthPercent
);
invokeMethod
(
"setMinHeight"
,
widthHint
,
heightHint
,
view
,
clazz
,
info
.
minHeightPercent
);
}
catch
(
NoSuchMethodException
e
)
{
e
.
printStackTrace
();
}
catch
(
InvocationTargetException
e
)
{
e
.
printStackTrace
();
}
catch
(
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
}
private
void
invokeMethod
(
String
methodName
,
int
widthHint
,
int
heightHint
,
View
view
,
Class
clazz
,
PercentLayoutInfo
.
PercentVal
percentVal
)
throws
NoSuchMethodException
,
IllegalAccessException
,
InvocationTargetException
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
Log
.
d
(
TAG
,
methodName
+
" ==> "
+
percentVal
);
if
(
percentVal
!=
null
)
{
Method
setMaxWidthMethod
=
clazz
.
getMethod
(
methodName
,
int
.
class
);
setMaxWidthMethod
.
setAccessible
(
true
);
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
percentVal
.
basemode
);
setMaxWidthMethod
.
invoke
(
view
,
(
int
)
(
base
*
percentVal
.
percent
));
}
}
private
void
supportTextSize
(
int
widthHint
,
int
heightHint
,
View
view
,
PercentLayoutInfo
info
)
{
//textsize percent support
PercentLayoutInfo
.
PercentVal
textSizePercent
=
info
.
textSizePercent
;
if
(
textSizePercent
==
null
)
return
;
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
textSizePercent
.
basemode
);
float
textSize
=
(
int
)
(
base
*
textSizePercent
.
percent
);
//Button 和 EditText 是TextView的子类
if
(
view
instanceof
TextView
)
{
((
TextView
)
view
).
setTextSize
(
TypedValue
.
COMPLEX_UNIT_PX
,
textSize
);
}
}
private
static
int
getBaseByModeAndVal
(
int
widthHint
,
int
heightHint
,
PercentLayoutInfo
.
BASEMODE
basemode
)
{
switch
(
basemode
)
{
case
BASE_HEIGHT:
return
heightHint
;
case
BASE_WIDTH:
return
widthHint
;
case
BASE_SCREEN_WIDTH:
return
mWidthScreen
;
case
BASE_SCREEN_HEIGHT:
return
mHeightScreen
;
}
return
0
;
}
/**
* Constructs a PercentLayoutInfo from attributes associated with a View. Call this method from
* {@code LayoutParams(Context c, AttributeSet attrs)} constructor.
*/
public
static
PercentLayoutInfo
getPercentLayoutInfo
(
Context
context
,
AttributeSet
attrs
)
{
PercentLayoutInfo
info
=
null
;
TypedArray
array
=
context
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
PercentLayout_Layout
);
info
=
setWidthAndHeightVal
(
array
,
info
);
info
=
setMarginRelatedVal
(
array
,
info
);
info
=
setTextSizeSupportVal
(
array
,
info
);
info
=
setMinMaxWidthHeightRelatedVal
(
array
,
info
);
info
=
setPaddingRelatedVal
(
array
,
info
);
array
.
recycle
();
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
{
Log
.
d
(
TAG
,
"constructed: "
+
info
);
}
return
info
;
}
private
static
PercentLayoutInfo
setWidthAndHeightVal
(
TypedArray
array
,
PercentLayoutInfo
info
)
{
PercentLayoutInfo
.
PercentVal
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_widthPercent
,
true
);
if
(
percentVal
!=
null
)
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
VERBOSE
))
{
Log
.
v
(
TAG
,
"percent width: "
+
percentVal
.
percent
);
}
info
=
checkForInfoExists
(
info
);
info
.
widthPercent
=
percentVal
;
}
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_heightPercent
,
false
);
if
(
percentVal
!=
null
)
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
VERBOSE
))
{
Log
.
v
(
TAG
,
"percent height: "
+
percentVal
.
percent
);
}
info
=
checkForInfoExists
(
info
);
info
.
heightPercent
=
percentVal
;
}
return
info
;
}
private
static
PercentLayoutInfo
setTextSizeSupportVal
(
TypedArray
array
,
PercentLayoutInfo
info
)
{
//textSizePercent 默认以高度作为基准
PercentLayoutInfo
.
PercentVal
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_textSizePercent
,
false
);
if
(
percentVal
!=
null
)
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
VERBOSE
))
{
Log
.
v
(
TAG
,
"percent text size: "
+
percentVal
.
percent
);
}
info
=
checkForInfoExists
(
info
);
info
.
textSizePercent
=
percentVal
;
}
return
info
;
}
private
static
PercentLayoutInfo
setMinMaxWidthHeightRelatedVal
(
TypedArray
array
,
PercentLayoutInfo
info
)
{
//maxWidth
PercentLayoutInfo
.
PercentVal
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_maxWidthPercent
,
true
);
if
(
percentVal
!=
null
)
{
info
=
checkForInfoExists
(
info
);
info
.
maxWidthPercent
=
percentVal
;
}
//maxHeight
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_maxHeightPercent
,
false
);
if
(
percentVal
!=
null
)
{
info
=
checkForInfoExists
(
info
);
info
.
maxHeightPercent
=
percentVal
;
}
//minWidth
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_minWidthPercent
,
true
);
if
(
percentVal
!=
null
)
{
info
=
checkForInfoExists
(
info
);
info
.
minWidthPercent
=
percentVal
;
}
//minHeight
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_minHeightPercent
,
false
);
if
(
percentVal
!=
null
)
{
info
=
checkForInfoExists
(
info
);
info
.
minHeightPercent
=
percentVal
;
}
return
info
;
}
private
static
PercentLayoutInfo
setMarginRelatedVal
(
TypedArray
array
,
PercentLayoutInfo
info
)
{
//默认margin参考宽度
PercentLayoutInfo
.
PercentVal
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_marginPercent
,
true
);
if
(
percentVal
!=
null
)
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
VERBOSE
))
{
Log
.
v
(
TAG
,
"percent margin: "
+
percentVal
.
percent
);
}
info
=
checkForInfoExists
(
info
);
info
.
leftMarginPercent
=
percentVal
;
info
.
topMarginPercent
=
percentVal
;
info
.
rightMarginPercent
=
percentVal
;
info
.
bottomMarginPercent
=
percentVal
;
}
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_marginLeftPercent
,
true
);
if
(
percentVal
!=
null
)
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
VERBOSE
))
{
Log
.
v
(
TAG
,
"percent left margin: "
+
percentVal
.
percent
);
}
info
=
checkForInfoExists
(
info
);
info
.
leftMarginPercent
=
percentVal
;
}
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_marginTopPercent
,
false
);
if
(
percentVal
!=
null
)
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
VERBOSE
))
{
Log
.
v
(
TAG
,
"percent top margin: "
+
percentVal
.
percent
);
}
info
=
checkForInfoExists
(
info
);
info
.
topMarginPercent
=
percentVal
;
}
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_marginRightPercent
,
true
);
if
(
percentVal
!=
null
)
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
VERBOSE
))
{
Log
.
v
(
TAG
,
"percent right margin: "
+
percentVal
.
percent
);
}
info
=
checkForInfoExists
(
info
);
info
.
rightMarginPercent
=
percentVal
;
}
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_marginBottomPercent
,
false
);
if
(
percentVal
!=
null
)
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
VERBOSE
))
{
Log
.
v
(
TAG
,
"percent bottom margin: "
+
percentVal
.
percent
);
}
info
=
checkForInfoExists
(
info
);
info
.
bottomMarginPercent
=
percentVal
;
}
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_marginStartPercent
,
true
);
if
(
percentVal
!=
null
)
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
VERBOSE
))
{
Log
.
v
(
TAG
,
"percent start margin: "
+
percentVal
.
percent
);
}
info
=
checkForInfoExists
(
info
);
info
.
startMarginPercent
=
percentVal
;
}
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_marginEndPercent
,
true
);
if
(
percentVal
!=
null
)
{
if
(
Log
.
isLoggable
(
TAG
,
Log
.
VERBOSE
))
{
Log
.
v
(
TAG
,
"percent end margin: "
+
percentVal
.
percent
);
}
info
=
checkForInfoExists
(
info
);
info
.
endMarginPercent
=
percentVal
;
}
return
info
;
}
/**
* 设置paddingPercent相关属性
*
* @param array
* @param info
*/
private
static
PercentLayoutInfo
setPaddingRelatedVal
(
TypedArray
array
,
PercentLayoutInfo
info
)
{
//默认padding以宽度为标准
PercentLayoutInfo
.
PercentVal
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_paddingPercent
,
true
);
if
(
percentVal
!=
null
)
{
info
=
checkForInfoExists
(
info
);
info
.
paddingLeftPercent
=
percentVal
;
info
.
paddingRightPercent
=
percentVal
;
info
.
paddingBottomPercent
=
percentVal
;
info
.
paddingTopPercent
=
percentVal
;
}
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_paddingLeftPercent
,
true
);
if
(
percentVal
!=
null
)
{
info
=
checkForInfoExists
(
info
);
info
.
paddingLeftPercent
=
percentVal
;
}
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_paddingRightPercent
,
true
);
if
(
percentVal
!=
null
)
{
info
=
checkForInfoExists
(
info
);
info
.
paddingRightPercent
=
percentVal
;
}
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_paddingTopPercent
,
true
);
if
(
percentVal
!=
null
)
{
info
=
checkForInfoExists
(
info
);
info
.
paddingTopPercent
=
percentVal
;
}
percentVal
=
getPercentVal
(
array
,
R
.
styleable
.
PercentLayout_Layout_layout_paddingBottomPercent
,
true
);
if
(
percentVal
!=
null
)
{
info
=
checkForInfoExists
(
info
);
info
.
paddingBottomPercent
=
percentVal
;
}
return
info
;
}
private
static
PercentLayoutInfo
.
PercentVal
getPercentVal
(
TypedArray
array
,
int
index
,
boolean
baseWidth
)
{
String
sizeStr
=
array
.
getString
(
index
);
PercentLayoutInfo
.
PercentVal
percentVal
=
getPercentVal
(
sizeStr
,
baseWidth
);
return
percentVal
;
}
@NonNull
private
static
PercentLayoutInfo
checkForInfoExists
(
PercentLayoutInfo
info
)
{
info
=
info
!=
null
?
info
:
new
PercentLayoutInfo
();
return
info
;
}
private
static
final
String
REGEX_PERCENT
=
"^(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)%([s]?[wh]?)$"
;
/**
* widthStr to PercentVal
* <br/>
* eg: 35%w => new PercentVal(35, true)
*
* @param percentStr
* @param isOnWidth
* @return
*/
private
static
PercentLayoutInfo
.
PercentVal
getPercentVal
(
String
percentStr
,
boolean
isOnWidth
)
{
//valid param
if
(
percentStr
==
null
)
{
return
null
;
}
Pattern
p
=
Pattern
.
compile
(
REGEX_PERCENT
);
Matcher
matcher
=
p
.
matcher
(
percentStr
);
if
(!
matcher
.
matches
())
{
throw
new
RuntimeException
(
"the value of layout_xxxPercent invalid! ==>"
+
percentStr
);
}
int
len
=
percentStr
.
length
();
//extract the float value
String
floatVal
=
matcher
.
group
(
1
);
String
lastAlpha
=
percentStr
.
substring
(
len
-
1
);
float
percent
=
Float
.
parseFloat
(
floatVal
)
/
100
f
;
PercentLayoutInfo
.
PercentVal
percentVal
=
new
PercentLayoutInfo
.
PercentVal
();
percentVal
.
percent
=
percent
;
if
(
percentStr
.
endsWith
(
PercentLayoutInfo
.
BASEMODE
.
SW
))
{
percentVal
.
basemode
=
PercentLayoutInfo
.
BASEMODE
.
BASE_SCREEN_WIDTH
;
}
else
if
(
percentStr
.
endsWith
(
PercentLayoutInfo
.
BASEMODE
.
SH
))
{
percentVal
.
basemode
=
PercentLayoutInfo
.
BASEMODE
.
BASE_SCREEN_HEIGHT
;
}
else
if
(
percentStr
.
endsWith
(
PercentLayoutInfo
.
BASEMODE
.
PERCENT
))
{
if
(
isOnWidth
)
{
percentVal
.
basemode
=
PercentLayoutInfo
.
BASEMODE
.
BASE_WIDTH
;
}
else
{
percentVal
.
basemode
=
PercentLayoutInfo
.
BASEMODE
.
BASE_HEIGHT
;
}
}
else
if
(
percentStr
.
endsWith
(
PercentLayoutInfo
.
BASEMODE
.
W
))
{
percentVal
.
basemode
=
PercentLayoutInfo
.
BASEMODE
.
BASE_WIDTH
;
}
else
if
(
percentStr
.
endsWith
(
PercentLayoutInfo
.
BASEMODE
.
H
))
{
percentVal
.
basemode
=
PercentLayoutInfo
.
BASEMODE
.
BASE_HEIGHT
;
}
else
{
throw
new
IllegalArgumentException
(
"the "
+
percentStr
+
" must be endWith [%|w|h|sw|sh]"
);
}
return
percentVal
;
}
/**
* Iterates over children and restores their original dimensions that were changed for
* percentage values. Calling this method only makes sense if you previously called
* {@link PercentLayoutHelper#adjustChildren(int, int)}.
*/
public
void
restoreOriginalParams
()
{
for
(
int
i
=
0
,
N
=
mHost
.
getChildCount
();
i
<
N
;
i
++)
{
View
view
=
mHost
.
getChildAt
(
i
);
ViewGroup
.
LayoutParams
params
=
view
.
getLayoutParams
();
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
{
Log
.
d
(
TAG
,
"should restore "
+
view
+
" "
+
params
);
}
if
(
params
instanceof
PercentLayoutParams
)
{
PercentLayoutInfo
info
=
((
PercentLayoutParams
)
params
).
getPercentLayoutInfo
();
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
{
Log
.
d
(
TAG
,
"using "
+
info
);
}
if
(
info
!=
null
)
{
if
(
params
instanceof
ViewGroup
.
MarginLayoutParams
)
{
info
.
restoreMarginLayoutParams
((
ViewGroup
.
MarginLayoutParams
)
params
);
}
else
{
info
.
restoreLayoutParams
(
params
);
}
}
}
}
}
/**
* Iterates over children and checks if any of them would like to get more space than it
* received through the percentage dimension.
* <p/>
* If you are building a layout that supports percentage dimensions you are encouraged to take
* advantage of this method. The developer should be able to specify that a child should be
* remeasured by adding normal dimension attribute with {@code wrap_content} value. For example
* he might specify child's attributes as {@code app:layout_widthPercent="60%p"} and
* {@code android:layout_width="wrap_content"}. In this case if the child receives too little
* space, it will be remeasured with width set to {@code WRAP_CONTENT}.
*
* @return True if the measure phase needs to be rerun because one of the children would like
* to receive more space.
*/
public
boolean
handleMeasuredStateTooSmall
()
{
boolean
needsSecondMeasure
=
false
;
for
(
int
i
=
0
,
N
=
mHost
.
getChildCount
();
i
<
N
;
i
++)
{
View
view
=
mHost
.
getChildAt
(
i
);
ViewGroup
.
LayoutParams
params
=
view
.
getLayoutParams
();
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
{
Log
.
d
(
TAG
,
"should handle measured state too small "
+
view
+
" "
+
params
);
}
if
(
params
instanceof
PercentLayoutParams
)
{
PercentLayoutInfo
info
=
((
PercentLayoutParams
)
params
).
getPercentLayoutInfo
();
if
(
info
!=
null
)
{
if
(
shouldHandleMeasuredWidthTooSmall
(
view
,
info
))
{
needsSecondMeasure
=
true
;
params
.
width
=
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
;
}
if
(
shouldHandleMeasuredHeightTooSmall
(
view
,
info
))
{
needsSecondMeasure
=
true
;
params
.
height
=
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
;
}
}
}
}
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
{
Log
.
d
(
TAG
,
"should trigger second measure pass: "
+
needsSecondMeasure
);
}
return
needsSecondMeasure
;
}
private
static
boolean
shouldHandleMeasuredWidthTooSmall
(
View
view
,
PercentLayoutInfo
info
)
{
int
state
=
ViewCompat
.
getMeasuredWidthAndState
(
view
)
&
ViewCompat
.
MEASURED_STATE_MASK
;
if
(
info
==
null
||
info
.
widthPercent
==
null
)
{
return
false
;
}
return
state
==
ViewCompat
.
MEASURED_STATE_TOO_SMALL
&&
info
.
widthPercent
.
percent
>=
0
&&
info
.
mPreservedParams
.
width
==
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
;
}
private
static
boolean
shouldHandleMeasuredHeightTooSmall
(
View
view
,
PercentLayoutInfo
info
)
{
int
state
=
ViewCompat
.
getMeasuredHeightAndState
(
view
)
&
ViewCompat
.
MEASURED_STATE_MASK
;
if
(
info
==
null
||
info
.
heightPercent
==
null
)
{
return
false
;
}
return
state
==
ViewCompat
.
MEASURED_STATE_TOO_SMALL
&&
info
.
heightPercent
.
percent
>=
0
&&
info
.
mPreservedParams
.
height
==
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
;
}
/**
* Container for information about percentage dimensions and margins. It acts as an extension
* for {@code LayoutParams}.
*/
public
static
class
PercentLayoutInfo
{
private
enum
BASEMODE
{
BASE_WIDTH
,
BASE_HEIGHT
,
BASE_SCREEN_WIDTH
,
BASE_SCREEN_HEIGHT
;
/**
* width_parent
*/
public
static
final
String
PERCENT
=
"%"
;
/**
* width_parent
*/
public
static
final
String
W
=
"w"
;
/**
* height_parent
*/
public
static
final
String
H
=
"h"
;
/**
* width_screen
*/
public
static
final
String
SW
=
"sw"
;
/**
* height_screen
*/
public
static
final
String
SH
=
"sh"
;
}
public
static
class
PercentVal
{
public
float
percent
=
-
1
;
public
BASEMODE
basemode
;
public
PercentVal
()
{
}
public
PercentVal
(
float
percent
,
BASEMODE
baseMode
)
{
this
.
percent
=
percent
;
this
.
basemode
=
baseMode
;
}
@Override
public
String
toString
()
{
return
"PercentVal{"
+
"percent="
+
percent
+
", basemode="
+
basemode
.
name
()
+
'}'
;
}
}
public
PercentVal
widthPercent
;
public
PercentVal
heightPercent
;
public
PercentVal
leftMarginPercent
;
public
PercentVal
topMarginPercent
;
public
PercentVal
rightMarginPercent
;
public
PercentVal
bottomMarginPercent
;
public
PercentVal
startMarginPercent
;
public
PercentVal
endMarginPercent
;
public
PercentVal
textSizePercent
;
//1.0.4 those attr for some views' setMax/min Height/Width method
public
PercentVal
maxWidthPercent
;
public
PercentVal
maxHeightPercent
;
public
PercentVal
minWidthPercent
;
public
PercentVal
minHeightPercent
;
//1.0.6 add padding supprot
public
PercentVal
paddingLeftPercent
;
public
PercentVal
paddingRightPercent
;
public
PercentVal
paddingTopPercent
;
public
PercentVal
paddingBottomPercent
;
/* package */
final
ViewGroup
.
MarginLayoutParams
mPreservedParams
;
public
PercentLayoutInfo
()
{
mPreservedParams
=
new
ViewGroup
.
MarginLayoutParams
(
0
,
0
);
}
/**
* Fills {@code ViewGroup.LayoutParams} dimensions based on percentage values.
*/
public
void
fillLayoutParams
(
ViewGroup
.
LayoutParams
params
,
int
widthHint
,
int
heightHint
)
{
// Preserve the original layout params, so we can restore them after the measure step.
mPreservedParams
.
width
=
params
.
width
;
mPreservedParams
.
height
=
params
.
height
;
if
(
widthPercent
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
widthPercent
.
basemode
);
params
.
width
=
(
int
)
(
base
*
widthPercent
.
percent
);
}
if
(
heightPercent
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
heightPercent
.
basemode
);
params
.
height
=
(
int
)
(
base
*
heightPercent
.
percent
);
}
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
{
Log
.
d
(
TAG
,
"after fillLayoutParams: ("
+
params
.
width
+
", "
+
params
.
height
+
")"
);
}
}
/**
* Fills {@code ViewGroup.MarginLayoutParams} dimensions and margins based on percentage
* values.
*/
public
void
fillMarginLayoutParams
(
ViewGroup
.
MarginLayoutParams
params
,
int
widthHint
,
int
heightHint
)
{
fillLayoutParams
(
params
,
widthHint
,
heightHint
);
// Preserver the original margins, so we can restore them after the measure step.
mPreservedParams
.
leftMargin
=
params
.
leftMargin
;
mPreservedParams
.
topMargin
=
params
.
topMargin
;
mPreservedParams
.
rightMargin
=
params
.
rightMargin
;
mPreservedParams
.
bottomMargin
=
params
.
bottomMargin
;
MarginLayoutParamsCompat
.
setMarginStart
(
mPreservedParams
,
MarginLayoutParamsCompat
.
getMarginStart
(
params
));
MarginLayoutParamsCompat
.
setMarginEnd
(
mPreservedParams
,
MarginLayoutParamsCompat
.
getMarginEnd
(
params
));
if
(
leftMarginPercent
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
leftMarginPercent
.
basemode
);
params
.
leftMargin
=
(
int
)
(
base
*
leftMarginPercent
.
percent
);
}
if
(
topMarginPercent
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
topMarginPercent
.
basemode
);
params
.
topMargin
=
(
int
)
(
base
*
topMarginPercent
.
percent
);
}
if
(
rightMarginPercent
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
rightMarginPercent
.
basemode
);
params
.
rightMargin
=
(
int
)
(
base
*
rightMarginPercent
.
percent
);
}
if
(
bottomMarginPercent
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
bottomMarginPercent
.
basemode
);
params
.
bottomMargin
=
(
int
)
(
base
*
bottomMarginPercent
.
percent
);
}
if
(
startMarginPercent
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
startMarginPercent
.
basemode
);
MarginLayoutParamsCompat
.
setMarginStart
(
params
,
(
int
)
(
base
*
startMarginPercent
.
percent
));
}
if
(
endMarginPercent
!=
null
)
{
int
base
=
getBaseByModeAndVal
(
widthHint
,
heightHint
,
endMarginPercent
.
basemode
);
MarginLayoutParamsCompat
.
setMarginEnd
(
params
,
(
int
)
(
base
*
endMarginPercent
.
percent
));
}
if
(
Log
.
isLoggable
(
TAG
,
Log
.
DEBUG
))
{
Log
.
d
(
TAG
,
"after fillMarginLayoutParams: ("
+
params
.
width
+
", "
+
params
.
height
+
")"
);
}
}
@Override
public
String
toString
()
{
return
"PercentLayoutInfo{"
+
"widthPercent="
+
widthPercent
+
", heightPercent="
+
heightPercent
+
", leftMarginPercent="
+
leftMarginPercent
+
", topMarginPercent="
+
topMarginPercent
+
", rightMarginPercent="
+
rightMarginPercent
+
", bottomMarginPercent="
+
bottomMarginPercent
+
", startMarginPercent="
+
startMarginPercent
+
", endMarginPercent="
+
endMarginPercent
+
", textSizePercent="
+
textSizePercent
+
", maxWidthPercent="
+
maxWidthPercent
+
", maxHeightPercent="
+
maxHeightPercent
+
", minWidthPercent="
+
minWidthPercent
+
", minHeightPercent="
+
minHeightPercent
+
", paddingLeftPercent="
+
paddingLeftPercent
+
", paddingRightPercent="
+
paddingRightPercent
+
", paddingTopPercent="
+
paddingTopPercent
+
", paddingBottomPercent="
+
paddingBottomPercent
+
", mPreservedParams="
+
mPreservedParams
+
'}'
;
}
/**
* Restores original dimensions and margins after they were changed for percentage based
* values. Calling this method only makes sense if you previously called
* {@link PercentLayoutHelper.PercentLayoutInfo#fillMarginLayoutParams}.
*/
public
void
restoreMarginLayoutParams
(
ViewGroup
.
MarginLayoutParams
params
)
{
restoreLayoutParams
(
params
);
params
.
leftMargin
=
mPreservedParams
.
leftMargin
;
params
.
topMargin
=
mPreservedParams
.
topMargin
;
params
.
rightMargin
=
mPreservedParams
.
rightMargin
;
params
.
bottomMargin
=
mPreservedParams
.
bottomMargin
;
MarginLayoutParamsCompat
.
setMarginStart
(
params
,
MarginLayoutParamsCompat
.
getMarginStart
(
mPreservedParams
));
MarginLayoutParamsCompat
.
setMarginEnd
(
params
,
MarginLayoutParamsCompat
.
getMarginEnd
(
mPreservedParams
));
}
/**
* Restores original dimensions after they were changed for percentage based values. Calling
* this method only makes sense if you previously called
* {@link PercentLayoutHelper.PercentLayoutInfo#fillLayoutParams}.
*/
public
void
restoreLayoutParams
(
ViewGroup
.
LayoutParams
params
)
{
params
.
width
=
mPreservedParams
.
width
;
params
.
height
=
mPreservedParams
.
height
;
}
}
/**
* If a layout wants to support percentage based dimensions and use this helper class, its
* {@code LayoutParams} subclass must implement this interface.
* <p/>
* Your {@code LayoutParams} subclass should contain an instance of {@code PercentLayoutInfo}
* and the implementation of this interface should be a simple accessor.
*/
public
interface
PercentLayoutParams
{
PercentLayoutInfo
getPercentLayoutInfo
();
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/label/customview/PercentRelativeLayout.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
customview
;
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
android.content.Context
;
import
android.content.res.TypedArray
;
import
android.util.AttributeSet
;
import
android.view.ViewGroup
;
import
android.widget.RelativeLayout
;
/**
* Subclass of {@link RelativeLayout} that supports percentage based dimensions and
* margins.
*
* You can specify dimension or a margin of child by using attributes with "Percent" suffix. Follow
* this example:
*
* <pre class="prettyprint">
* <android.support.percent.PercentRelativeLayout
* xmlns:android="http://schemas.android.com/apk/res/android"
* xmlns:app="http://schemas.android.com/apk/res-auto"
* android:layout_width="match_parent"
* android:layout_height="match_parent"/>
* <ImageView
* app:layout_widthPercent="50%"
* app:layout_heightPercent="50%"
* app:layout_marginTopPercent="25%"
* app:layout_marginLeftPercent="25%"/>
* </android.support.percent.PercentFrameLayout/>
* </pre>
*
* The attributes that you can use are:
* <ul>
* <li>{@code layout_widthPercent}
* <li>{@code layout_heightPercent}
* <li>{@code layout_marginPercent}
* <li>{@code layout_marginLeftPercent}
* <li>{@code layout_marginTopPercent}
* <li>{@code layout_marginRightPercent}
* <li>{@code layout_marginBottomPercent}
* <li>{@code layout_marginStartPercent}
* <li>{@code layout_marginEndPercent}
* </ul>
*
* It is not necessary to specify {@code layout_width/height} if you specify {@code
* layout_widthPercent.} However, if you want the view to be able to take up more space than what
* percentage value permits, you can add {@code layout_width/height="wrap_content"}. In that case
* if the percentage size is too small for the View's content, it will be resized using
* {@code wrap_content} rule.
*/
public
class
PercentRelativeLayout
extends
RelativeLayout
{
private
final
PercentLayoutHelper
mHelper
=
new
PercentLayoutHelper
(
this
);
public
PercentRelativeLayout
(
Context
context
)
{
super
(
context
);
}
public
PercentRelativeLayout
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
public
PercentRelativeLayout
(
Context
context
,
AttributeSet
attrs
,
int
defStyle
)
{
super
(
context
,
attrs
,
defStyle
);
}
@Override
public
LayoutParams
generateLayoutParams
(
AttributeSet
attrs
)
{
return
new
LayoutParams
(
getContext
(),
attrs
);
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
mHelper
.
adjustChildren
(
widthMeasureSpec
,
heightMeasureSpec
);
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
if
(
mHelper
.
handleMeasuredStateTooSmall
())
{
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
}
}
@Override
protected
void
onLayout
(
boolean
changed
,
int
left
,
int
top
,
int
right
,
int
bottom
)
{
super
.
onLayout
(
changed
,
left
,
top
,
right
,
bottom
);
mHelper
.
restoreOriginalParams
();
}
public
static
class
LayoutParams
extends
RelativeLayout
.
LayoutParams
implements
PercentLayoutHelper
.
PercentLayoutParams
{
private
PercentLayoutHelper
.
PercentLayoutInfo
mPercentLayoutInfo
;
public
LayoutParams
(
Context
c
,
AttributeSet
attrs
)
{
super
(
c
,
attrs
);
mPercentLayoutInfo
=
PercentLayoutHelper
.
getPercentLayoutInfo
(
c
,
attrs
);
}
public
LayoutParams
(
int
width
,
int
height
)
{
super
(
width
,
height
);
}
public
LayoutParams
(
ViewGroup
.
LayoutParams
source
)
{
super
(
source
);
}
public
LayoutParams
(
MarginLayoutParams
source
)
{
super
(
source
);
}
@Override
public
PercentLayoutHelper
.
PercentLayoutInfo
getPercentLayoutInfo
()
{
return
mPercentLayoutInfo
;
}
@Override
protected
void
setBaseAttributes
(
TypedArray
a
,
int
widthAttr
,
int
heightAttr
)
{
PercentLayoutHelper
.
fetchWidthAndHeight
(
this
,
a
,
widthAttr
,
heightAttr
);
}
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/label/customview/verticalViewPager.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
customview
;
import
android.content.Context
;
import
android.util.AttributeSet
;
import
androidx.viewpager.widget.ViewPager
;
/**
* Created by Administrator on 2016/8/24.
*/
/*
* 在普通 ViewPager 上实现向上滑动删除 一个Item
*/
public
class
verticalViewPager
extends
ViewPager
{
public
verticalViewPager
(
Context
context
)
{
super
(
context
);
}
public
verticalViewPager
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
}
app/src/main/java/com/base/browserwhite/label/event/baseEvent.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
event
;
/**
* Created by Administrator on 2016/8/23.
*/
public
class
baseEvent
{
}
app/src/main/java/com/base/browserwhite/label/event/delThisFrag.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
event
;
/**
* Created by Administrator on 2016/8/25.
*/
public
class
delThisFrag
extends
baseEvent
{
//fragment发出,通知anctvity删除自己
}
app/src/main/java/com/base/browserwhite/label/event/deleteFragEvent.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
event
;
/**
* Created by Administrator on 2016/8/24.
*/
public
class
deleteFragEvent
extends
baseEvent
{
//如果fragment 上滑到一半,就会发出删除信号
String
fragTag
;
public
deleteFragEvent
(
String
fragTag
)
{
this
.
fragTag
=
fragTag
;
}
public
String
getFragTag
()
{
return
fragTag
;
}
public
void
setFragTag
(
String
fragTag
)
{
this
.
fragTag
=
fragTag
;
}
}
app/src/main/java/com/base/browserwhite/label/event/fragEvent.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
event
;
/**
* Created by Administrator on 2016/8/23.
*/
public
class
fragEvent
extends
baseEvent
{
//用于传递 fragment的tag
String
fragTag
;
public
fragEvent
(
String
fragTag
)
{
this
.
fragTag
=
fragTag
;
}
public
String
getFragTag
()
{
return
fragTag
;
}
public
void
setFragTag
(
String
fragTag
)
{
this
.
fragTag
=
fragTag
;
}
}
app/src/main/java/com/base/browserwhite/label/event/showDelImg.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
event
;
/**
* Created by Administrator on 2016/8/25.
*/
//显示删除按钮
public
class
showDelImg
extends
baseEvent
{
private
boolean
isShow
;
public
showDelImg
(
boolean
isShow
)
{
this
.
isShow
=
isShow
;
}
public
boolean
isShow
()
{
return
isShow
;
}
public
void
setIsShow
(
boolean
isShow
)
{
this
.
isShow
=
isShow
;
}
}
app/src/main/java/com/base/browserwhite/label/event/slideEvent.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
event
;
/**
* Created by Administrator on 2016/8/23.
*/
//viewpager缩小后点击 viewpager控件的左边或者右边 发出的事件
public
class
slideEvent
extends
baseEvent
{
private
int
type
;
//事件类型:点击 ACTION_DOWN ,滑动 ACTION_MOVE
private
String
direction
;
//点击位置 或者 滑动方向
public
slideEvent
(
int
type
,
String
direction
)
{
this
.
type
=
type
;
this
.
direction
=
direction
;
}
public
int
getType
()
{
return
type
;
}
public
String
getDirection
()
{
return
direction
;
}
public
void
setType
(
int
type
)
{
this
.
type
=
type
;
}
public
void
setDirection
(
String
direction
)
{
this
.
direction
=
direction
;
}
}
app/src/main/java/com/base/browserwhite/label/event/zoomEvent.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
event
;
/**
* Created by Administrator on 2016/8/25.
*/
public
class
zoomEvent
extends
baseEvent
{
//viewpager当前的状态,放大或缩小
private
boolean
isMatchParent
;
//viewpager 当前是不是 MatchParent
public
zoomEvent
(
boolean
isMatchParent
)
{
this
.
isMatchParent
=
isMatchParent
;
}
public
boolean
isMatchParent
()
{
return
isMatchParent
;
}
public
void
setIsMatchParent
(
boolean
isMatchParent
)
{
this
.
isMatchParent
=
isMatchParent
;
}
}
app/src/main/java/com/base/browserwhite/label/fragment/baseFrag.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
fragment
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
androidx.fragment.app.Fragment
;
/**
* Created by Administrator on 2016/8/23.
*/
public
class
baseFrag
extends
Fragment
implements
View
.
OnTouchListener
{
protected
float
point_x
,
point_y
;
//手指按下的位置
private
boolean
flag
;
@Override
public
boolean
onTouch
(
View
v
,
MotionEvent
event
)
{
if
(
event
.
getAction
()
==
MotionEvent
.
ACTION_DOWN
)
{
point_x
=
event
.
getX
();
point_y
=
event
.
getY
();
flag
=
false
;
}
return
true
;
}
}
app/src/main/java/com/base/browserwhite/label/fragment/fragAdapter.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
fragment
;
import
android.content.Context
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
androidx.fragment.app.Fragment
;
import
androidx.fragment.app.FragmentManager
;
import
androidx.fragment.app.FragmentStatePagerAdapter
;
import
com.base.browserwhite.label.constance.fragConst
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.util.List
;
/**
* Created by Administrator on 2016/8/20.
*/
public
class
fragAdapter
extends
FragmentStatePagerAdapter
{
private
Context
context
;
private
FragmentManager
fm
;
public
fragAdapter
(
Context
context
,
FragmentManager
fm
)
{
super
(
fm
);
this
.
context
=
context
;
this
.
fm
=
fm
;
}
@Override
public
Fragment
getItem
(
int
position
)
{
return
fragConst
.
fraglist
.
get
(
position
);
}
@Override
public
int
getCount
()
{
// Logger.v("fragConst.fraglist.size() "+fragConst.fraglist.size());
return
fragConst
.
fraglist
.
size
();
}
@Override
public
Object
instantiateItem
(
ViewGroup
container
,
int
position
)
{
return
super
.
instantiateItem
(
container
,
position
);
}
@Override
public
int
getItemPosition
(
Object
object
)
{
// try {
// Method method = object.getClass().getMethod(("getFragTag"),new Class[0] );
// String tag= (String) method.invoke(object,new Object[0]);
// if( isDel ){
// if( tag.equals(""+id ) ){
// Logger.d("删除项tag= "+tag+ " id= " + id );
// return POSITION_NONE;
// }else {
// return POSITION_UNCHANGED;
// }
// }else {
// return POSITION_UNCHANGED;
// }
// } catch (NoSuchMethodException e) {
// e.printStackTrace();
// } catch (InvocationTargetException e) {
// Logger.d("getItemPosition InvocationTargetException" );
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// Logger.d("getItemPosition IllegalAccessException" );
// e.printStackTrace();
// }
//需要实现一种机制避免更新所有的fragment
return
POSITION_NONE
;
}
@Override
public
void
destroyItem
(
ViewGroup
container
,
int
position
,
Object
object
)
{
super
.
destroyItem
(
container
,
position
,
object
);
}
}
app/src/main/java/com/base/browserwhite/label/fragment/mainFrag.java
0 → 100644
View file @
163e8389
package
com
.
base
.
browserwhite
.
label
.
fragment
;
import
android.animation.ObjectAnimator
;
import
android.animation.PropertyValuesHolder
;
import
android.content.Context
;
import
android.graphics.Color
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.util.DisplayMetrics
;
import
android.util.Log
;
import
android.view.LayoutInflater
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.FrameLayout
;
import
android.widget.ImageView
;
import
android.widget.LinearLayout
;
import
android.widget.RelativeLayout
;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
androidx.annotation.Nullable
;
import
com.base.browserwhite.R
;
import
com.base.browserwhite.label.event.delThisFrag
;
import
com.base.browserwhite.label.event.deleteFragEvent
;
import
com.base.browserwhite.label.event.fragEvent
;
import
com.base.browserwhite.label.event.showDelImg
;
import
com.base.browserwhite.label.event.zoomEvent
;
import
com.base.browserwhite.label.constance.fragConst
;
import
com.base.browserwhite.label.event.baseEvent
;
import
org.greenrobot.eventbus.EventBus
;
import
org.greenrobot.eventbus.Subscribe
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Random
;
/**
* Created by Administrator on 2016/8/20.
*/
public
class
mainFrag
extends
baseFrag
{
private
RelativeLayout
mainrlt
;
private
TextView
showtitletv
;
private
LinearLayout
showtitlelt
;
private
FrameLayout
rootlt
;
private
DisplayMetrics
dm2
;
private
String
fragTag
=
""
;
private
ImageView
delthispage
;
private
boolean
isNewFragment
=
false
;
private
int
color
;
public
mainFrag
()
{
this
.
fragTag
=
fragConst
.
new_mainfrag_count
+
""
;
fragConst
.
new_mainfrag_count
++;
isNewFragment
=
true
;
}
@Nullable
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
ViewGroup
container
,
Bundle
savedInstanceState
)
{
View
view
=
inflater
.
inflate
(
R
.
layout
.
fragment_label
,
container
,
false
);
mainrlt
=
(
RelativeLayout
)
view
.
findViewById
(
R
.
id
.
mainrlt
);
mainrlt
.
setOnTouchListener
(
this
);
rootlt
=
(
FrameLayout
)
view
.
findViewById
(
R
.
id
.
rootlt
);
rootlt
.
setOnTouchListener
(
this
);
delthispage
=
(
ImageView
)
view
.
findViewById
(
R
.
id
.
delthispage
);
showtitlelt
=
(
LinearLayout
)
view
.
findViewById
(
R
.
id
.
showtitlelt
);
showtitletv
=
(
TextView
)
view
.
findViewById
(
R
.
id
.
showtitletv
);
EventBus
.
getDefault
().
register
(
this
);
init
(
view
);
return
view
;
}
private
void
init
(
View
view
)
{
dm2
=
getResources
().
getDisplayMetrics
();
TextView
showtag
=
(
TextView
)
view
.
findViewById
(
R
.
id
.
showtag
);
showtag
.
setText
(
"当前fragment "
+
getFragTag
());
delthispage
.
setOnClickListener
(
View
->
{
delAnime
();
new
Handler
().
postDelayed
(()
->
{
EventBus
.
getDefault
().
post
(
new
delThisFrag
());
// 发送消息
},
300
);
});
if
((
fragConst
.
new_mainfrag_count
>
1
)
&&
isNewFragment
)
{
//缩小
PropertyValuesHolder
pvhX
=
PropertyValuesHolder
.
ofFloat
(
"scaleX"
,
0.1f
,
1
f
);
PropertyValuesHolder
pvhY
=
PropertyValuesHolder
.
ofFloat
(
"scaleY"
,
0.1f
,
1
f
);
ObjectAnimator
scale
=
ObjectAnimator
.
ofPropertyValuesHolder
(
rootlt
,
pvhX
,
pvhY
);
scale
.
setDuration
(
50
);
scale
.
start
();
Random
random
=
new
Random
();
color
=
Color
.
rgb
(
random
.
nextInt
(
256
),
random
.
nextInt
(
256
),
random
.
nextInt
(
256
));
}
isNewFragment
=
false
;
if
(
color
!=
0
)
{
mainrlt
.
setBackgroundColor
(
color
);
}
}
public
String
getFragTag
()
{
// 被反射的方法
return
fragTag
;
}
public
void
setFragTag
(
String
fragTag
)
{
this
.
fragTag
=
fragTag
;
}
private
float
mov_x
,
mov_y
;
//相对于手指移动了的位置
private
int
left
,
right
,
top
,
bottom
;
private
List
<
int
[]>
positionlist
=
new
ArrayList
<>();
@Override
public
boolean
onTouch
(
View
v
,
MotionEvent
event
)
{
super
.
onTouch
(
v
,
event
);
if
(
event
.
getAction
()
==
MotionEvent
.
ACTION_DOWN
)
{
positionlist
.
clear
();
}
if
(
event
.
getAction
()
==
MotionEvent
.
ACTION_MOVE
)
{
// Logger.v("x: " + event.getX() + " y: " + event.getY());
mov_x
=
event
.
getX
()
-
super
.
point_x
;
mov_y
=
event
.
getY
()
-
super
.
point_y
;
left
=
mainrlt
.
getLeft
();
right
=
mainrlt
.
getRight
();
top
=
mainrlt
.
getTop
();
bottom
=
mainrlt
.
getBottom
();
if
(
Math
.
abs
(
dm2
.
widthPixels
-
mainrlt
.
getWidth
())
>
5
)
{
mainrlt
.
layout
(
left
,
top
+
(
int
)
mov_y
,
right
,
bottom
+
(
int
)
mov_y
);
int
[]
position
=
{
left
,
top
+
(
int
)
mov_y
,
right
,
bottom
+
(
int
)
mov_y
};
positionlist
.
add
(
position
);
// Logger.v("left " + position[0] + " top " + position[1] + " right " + position[2] + " bottom " + position[3] );
if
(
Math
.
abs
(
position
[
1
])
>
mainrlt
.
getWidth
()
/
2
)
{
// Logger.v("- 显示 删除 按钮 -");
EventBus
.
getDefault
().
post
(
new
showDelImg
(
true
));
// 发送消息
}
else
{
EventBus
.
getDefault
().
post
(
new
showDelImg
(
false
));
// 发送消息
}
}
}
if
(
event
.
getAction
()
==
MotionEvent
.
ACTION_UP
)
{
if
(
positionlist
.
size
()
>=
2
)
{
if
(
fragConst
.
fraglist
.
size
()>
1
&&
Math
.
abs
(
positionlist
.
get
(
positionlist
.
size
()
-
1
)[
1
])
>
mainrlt
.
getWidth
()
/
2
)
{
// Logger.v("- 删除 fragment -");
delAnime
();
EventBus
.
getDefault
().
post
(
new
showDelImg
(
false
));
// 发送消息
new
Handler
().
postDelayed
(()
->
{
EventBus
.
getDefault
().
post
(
new
deleteFragEvent
(
getFragTag
()));
// 发送消息
},
200
);
return
true
;
}
}
else
{
//放大或者缩小fragment
EventBus
.
getDefault
().
post
(
new
fragEvent
(
getFragTag
()));
// 发送消息
}
for
(
int
i
=
positionlist
.
size
()
-
1
;
i
>=
0
;
i
--)
{
mainrlt
.
layout
(
positionlist
.
get
(
i
)[
0
],
positionlist
.
get
(
i
)[
1
],
positionlist
.
get
(
i
)[
2
],
positionlist
.
get
(
i
)[
3
]);
}
mainrlt
.
layout
(
0
,
0
,
mainrlt
.
getWidth
(),
mainrlt
.
getHeight
());
}
return
true
;
}
//删除动画
private
void
delAnime
()
{
if
(
fragConst
.
fraglist
.
size
()
<=
1
)
{
return
;
}
PropertyValuesHolder
pvhX
=
PropertyValuesHolder
.
ofFloat
(
"scaleX"
,
1
f
,
0.01f
);
PropertyValuesHolder
pvhY
=
PropertyValuesHolder
.
ofFloat
(
"scaleY"
,
1
f
,
0.01f
);
ObjectAnimator
scalexy
=
ObjectAnimator
.
ofPropertyValuesHolder
(
mainrlt
,
pvhX
,
pvhY
);
ObjectAnimator
scale
=
ObjectAnimator
.
ofFloat
(
mainrlt
,
"translationY"
,
0
,
-
2500
);
scale
.
setDuration
(
200
);
scalexy
.
setDuration
(
200
);
scale
.
start
();
scalexy
.
start
();
}
@Subscribe
public
void
onEventMainThread
(
baseEvent
event
)
{
// Toast.makeText(getActivity(), " 收到 event 数据 ", 0).show();
if
(
event
instanceof
zoomEvent
)
{
if
(((
zoomEvent
)
event
).
isMatchParent
())
{
showtitlelt
.
setVisibility
(
View
.
INVISIBLE
);
}
else
{
showtitlelt
.
setVisibility
(
View
.
VISIBLE
);
}
}
}
@Override
public
void
onDestroyView
()
{
super
.
onDestroyView
();
EventBus
.
getDefault
().
unregister
(
this
);
}
}
app/src/main/java/com/base/browserwhite/ui/activity/MainActivity.kt
View file @
163e8389
...
@@ -17,6 +17,7 @@ import com.base.browserwhite.R
...
@@ -17,6 +17,7 @@ import com.base.browserwhite.R
import
com.base.browserwhite.bean.ConstObject.isFirstMainShow
import
com.base.browserwhite.bean.ConstObject.isFirstMainShow
import
com.base.browserwhite.bean.ConstObject.mainShowCount
import
com.base.browserwhite.bean.ConstObject.mainShowCount
import
com.base.browserwhite.databinding.ActivityMainBinding
import
com.base.browserwhite.databinding.ActivityMainBinding
import
com.base.browserwhite.label.LabelActivity
import
com.base.browserwhite.ui.activity.cleanjunk.ScanJunkActivity
import
com.base.browserwhite.ui.activity.cleanjunk.ScanJunkActivity
import
com.base.browserwhite.ui.activity.splash.Splash2Activity
import
com.base.browserwhite.ui.activity.splash.Splash2Activity
import
com.base.browserwhite.ui.fragment.FileFragment
import
com.base.browserwhite.ui.fragment.FileFragment
...
@@ -93,6 +94,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
...
@@ -93,6 +94,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
addDeskShortCut
()
addDeskShortCut
()
startActivity
(
Intent
(
this
,
LabelActivity
::
class
.
java
))
}
}
...
...
app/src/main/res/layout/fragment_label.xml
0 → 100644
View file @
163e8389
<FrameLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:id=
"@+id/rootlt"
>
<RelativeLayout
android:id=
"@+id/mainrlt"
android:background=
"#a0FFFF00"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<LinearLayout
android:id=
"@+id/showtitlelt"
android:visibility=
"invisible"
android:orientation=
"vertical"
android:background=
"#50000000"
android:layout_alignParentTop=
"true"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
<TextView
android:text=
"LeLo"
android:id=
"@+id/showtitletv"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
/>
</LinearLayout>
<TextView
android:textSize=
"40dp"
android:id=
"@+id/showtag"
android:text=
"showtag"
android:textColor=
"#FFFFFF"
android:layout_centerInParent=
"true"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
/>
<LinearLayout
android:orientation=
"vertical"
android:background=
"#50000000"
android:layout_alignParentBottom=
"true"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
<ImageView
android:layout_margin=
"5dp"
android:id=
"@+id/delthispage"
android:layout_gravity=
"center_horizontal"
android:background=
"@mipmap/reddit_115_local"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
/>
</LinearLayout>
</RelativeLayout>
</FrameLayout>
app/src/main/res/layout/label.xml
0 → 100644
View file @
163e8389
<?xml version="1.0" encoding="utf-8"?>
<com.base.browserwhite.label.customview.PercentRelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/mainrootrl"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_centerInParent=
"true"
android:background=
"#b0000000"
android:clipChildren=
"false"
android:layerType=
"software"
>
<LinearLayout
android:id=
"@+id/llayoutviewpage"
android:layout_width=
"0dp"
android:layout_height=
"0dp"
android:layout_centerInParent=
"true"
android:clickable=
"true"
android:clipChildren=
"false"
android:orientation=
"vertical"
app:layout_heightPercent=
"100%h"
app:layout_widthPercent=
"100%w"
>
<com.base.browserwhite.label.customview.verticalViewPager
android:id=
"@+id/mainviewpage"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:clipChildren=
"false"
></com.base.browserwhite.label.customview.verticalViewPager>
</LinearLayout>
<RelativeLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<ImageView
android:id=
"@+id/delfrag"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_centerHorizontal=
"true"
android:layout_marginTop=
"15dp"
android:background=
"@mipmap/del_chip"
android:visibility=
"invisible"
/>
</RelativeLayout>
<LinearLayout
android:id=
"@+id/mainbarlt"
android:layout_width=
"0dp"
android:layout_height=
"0dp"
android:layout_alignParentBottom=
"true"
android:orientation=
"vertical"
app:layout_heightPercent=
"8%h"
app:layout_widthPercent=
"100%w"
>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
<View
android:layout_width=
"fill_parent"
android:layout_height=
"1px"
android:layout_weight=
"1"
android:background=
"#000000"
>
</View>
</LinearLayout>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"#FFFFFF"
android:orientation=
"horizontal"
>
<ImageView
android:id=
"@+id/leftbt"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:background=
"@mipmap/ebay"
app:layout_marginLeftPercent=
"20%w"
/>
<ImageView
android:id=
"@+id/rightbt"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:background=
"@mipmap/right_n"
/>
<ImageView
android:id=
"@+id/setbt"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:background=
"@mipmap/search_bookmark"
/>
<TextView
android:id=
"@+id/pagebt"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:background=
"@mipmap/s_del"
android:gravity=
"center"
android:text=
"1"
/>
<ImageView
android:id=
"@+id/homebt"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:background=
"@mipmap/home"
/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id=
"@+id/pagebarlt"
android:layout_width=
"0dp"
android:layout_height=
"0dp"
android:layout_alignParentBottom=
"true"
android:layout_centerInParent=
"true"
android:orientation=
"vertical"
android:visibility=
"invisible"
app:layout_heightPercent=
"8%h"
app:layout_widthPercent=
"40%w"
>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"horizontal"
>
<ImageView
android:id=
"@+id/addnewpage"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:background=
"@mipmap/m_add_widget"
app:layout_marginLeftPercent=
"20%w"
/>
<ImageView
android:id=
"@+id/returnmain"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:background=
"@mipmap/reddit_115_local"
/>
</LinearLayout>
</LinearLayout>
</com.base.browserwhite.label.customview.PercentRelativeLayout>
app/src/main/res/values/attrs.xml
View file @
163e8389
...
@@ -4,4 +4,31 @@
...
@@ -4,4 +4,31 @@
<attr
name=
"appWidgetInnerRadius"
format=
"dimension"
/>
<attr
name=
"appWidgetInnerRadius"
format=
"dimension"
/>
<attr
name=
"appWidgetRadius"
format=
"dimension"
/>
<attr
name=
"appWidgetRadius"
format=
"dimension"
/>
</declare-styleable>
</declare-styleable>
<declare-styleable
name=
"PercentLayout_Layout"
>
<attr
name=
"layout_widthPercent"
format=
"string"
/>
<attr
name=
"layout_heightPercent"
format=
"string"
/>
<attr
name=
"layout_marginPercent"
format=
"string"
/>
<attr
name=
"layout_marginLeftPercent"
format=
"string"
/>
<attr
name=
"layout_marginTopPercent"
format=
"string"
/>
<attr
name=
"layout_marginRightPercent"
format=
"string"
/>
<attr
name=
"layout_marginBottomPercent"
format=
"string"
/>
<attr
name=
"layout_marginStartPercent"
format=
"string"
/>
<attr
name=
"layout_marginEndPercent"
format=
"string"
/>
<attr
name=
"layout_textSizePercent"
format=
"string"
/>
<attr
name=
"layout_maxWidthPercent"
format=
"string"
/>
<attr
name=
"layout_maxHeightPercent"
format=
"string"
/>
<attr
name=
"layout_minWidthPercent"
format=
"string"
/>
<attr
name=
"layout_minHeightPercent"
format=
"string"
/>
<attr
name=
"layout_paddingPercent"
format=
"string"
/>
<attr
name=
"layout_paddingTopPercent"
format=
"string"
/>
<attr
name=
"layout_paddingBottomPercent"
format=
"string"
/>
<attr
name=
"layout_paddingLeftPercent"
format=
"string"
/>
<attr
name=
"layout_paddingRightPercent"
format=
"string"
/>
</declare-styleable>
</resources>
</resources>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment