Skip to content

Commit b98920f

Browse files
author
fengpeng
committed
PhotoGroupView auto adapt column
1 parent c1f1600 commit b98920f

9 files changed

Lines changed: 104 additions & 67 deletions

File tree

app/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ android {
2525
dependencies {
2626
implementation fileTree(dir: 'libs', include: ['*.jar'])
2727
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
28-
implementation 'androidx.appcompat:appcompat:1.0.0'
29-
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
28+
implementation 'androidx.appcompat:appcompat:1.2.0'
29+
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
3030
testImplementation 'junit:junit:4.13.1'
31-
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
32-
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
31+
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
32+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
3333
implementation project(':picker')
3434
}

app/src/main/java/pizzk/media/picker/demo/MainActivity.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import android.annotation.SuppressLint
44
import android.net.Uri
55
import android.os.Bundle
66
import androidx.appcompat.app.AppCompatActivity
7-
import android.view.ViewGroup
87
import android.widget.ImageView
98
import android.widget.TextView
109
import pizzk.media.picker.arch.CropParams
@@ -24,10 +23,9 @@ class MainActivity : AppCompatActivity() {
2423
val photoGroup: PhotoGroupView = findViewById(R.id.photoGroup)
2524
val size: Int = resources.getDimensionPixelSize(R.dimen.x110)
2625
val tvHint: TextView = findViewById(R.id.tvHint)
27-
val lp: ViewGroup.LayoutParams = ViewGroup.LayoutParams(size, ViewGroup.LayoutParams.WRAP_CONTENT)
28-
val special: PhotoGroupView.Special = PhotoGroupView.Special(this@MainActivity, lp = lp, limit = 20, column = 4)
29-
photoGroup.setup(special, emptyList(), readOnly = false, appendText = "添加文件") {
30-
tvHint.text = "(${it.selectCount()}/${special.limit})"
26+
val special: PhotoGroupView.Special = PhotoGroupView.Special(this@MainActivity, limit = 20, column = 4)
27+
photoGroup.setup(special, emptyList(), readOnly = false, appendText = "添加文件") { adapter, _ ->
28+
tvHint.text = "(${adapter.selectCount()}/${special.limit})"
3129
}
3230
//单张选择示例
3331
val ivSingle: ImageView = findViewById(R.id.ivSingle)
Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<RelativeLayout
3-
xmlns:android="http://schemas.android.com/apk/res/android"
2+
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
44
xmlns:tools="http://schemas.android.com/tools"
55
android:layout_width="match_parent"
66
android:layout_height="match_parent"
@@ -11,53 +11,54 @@
1111
android:id="@+id/tvTitleMulti"
1212
android:layout_width="wrap_content"
1313
android:layout_height="wrap_content"
14-
android:layout_marginLeft="@dimen/pick_media_activity_margin"
14+
android:layout_marginStart="@dimen/pick_media_activity_margin"
1515
android:layout_marginTop="90dp"
1616
android:layout_marginBottom="@dimen/pick_media_activity_margin"
1717
android:text="@string/pick_demo_show"
1818
android:textColor="@color/pick_chose_text_color"
19-
android:textSize="18sp"/>
19+
android:textSize="18sp" />
2020

2121
<TextView
2222
android:id="@+id/tvHint"
2323
android:layout_width="wrap_content"
2424
android:layout_height="wrap_content"
2525
android:layout_alignTop="@+id/tvTitleMulti"
26-
android:layout_toRightOf="@+id/tvTitleMulti"
26+
android:layout_toEndOf="@+id/tvTitleMulti"
2727
android:text=""
2828
android:textColor="@color/pick_chose_text_color"
29-
android:textSize="18sp"/>
29+
android:textSize="18sp" />
3030

3131
<pizzk.media.picker.widget.PhotoGroupView
3232
android:id="@+id/photoGroup"
3333
android:layout_width="match_parent"
3434
android:layout_height="wrap_content"
3535
android:layout_below="@+id/tvTitleMulti"
3636
android:background="#00ffffff"
37-
android:paddingLeft="@dimen/pick_media_activity_margin"
37+
android:paddingStart="@dimen/pick_media_activity_margin"
3838
android:paddingTop="@dimen/pick_media_activity_margin"
39-
android:paddingRight="@dimen/pick_media_activity_margin"
40-
android:paddingBottom="@dimen/pick_media_activity_margin"/>
39+
android:paddingEnd="@dimen/pick_media_activity_margin"
40+
android:paddingBottom="@dimen/pick_media_activity_margin"
41+
app:space="2dp" />
4142

4243
<TextView
4344
android:id="@+id/tvTitleSingle"
4445
android:layout_width="wrap_content"
4546
android:layout_height="wrap_content"
4647
android:layout_below="@+id/photoGroup"
47-
android:layout_marginLeft="@dimen/pick_media_activity_margin"
48+
android:layout_marginStart="@dimen/pick_media_activity_margin"
4849
android:layout_marginTop="25dp"
4950
android:layout_marginBottom="@dimen/pick_media_activity_margin"
5051
android:text="@string/pick_sigle_photo"
5152
android:textColor="@color/pick_chose_text_color"
52-
android:textSize="18sp"/>
53+
android:textSize="18sp" />
5354

5455
<ImageView
5556
android:id="@+id/ivSingle"
5657
android:layout_width="90dp"
5758
android:layout_height="90dp"
5859
android:layout_below="@+id/tvTitleSingle"
59-
android:layout_marginLeft="@dimen/pick_media_activity_margin"
60+
android:layout_marginStart="@dimen/pick_media_activity_margin"
6061
android:background="@color/pick_chose_text_color"
61-
android:contentDescription="@string/description"/>
62+
android:contentDescription="@string/description" />
6263

6364
</RelativeLayout>

app/src/main/res/values/dimens.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33
<dimen name="x75">75dp</dimen>
4-
<dimen name="x110">110dp</dimen>
4+
<dimen name="x110">80dp</dimen>
55
</resources>

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ allprojects {
2525

2626
task clean(type: Delete) {
2727
delete rootProject.buildDir
28-
}
28+
}

picker/build.gradle

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ repositories {
2929

3030
dependencies {
3131
implementation fileTree(include: ['*.jar'], dir: 'libs')
32-
implementation 'androidx.appcompat:appcompat:1.0.0'
32+
implementation 'androidx.appcompat:appcompat:1.2.0'
3333
testImplementation 'junit:junit:4.13.1'
34-
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
35-
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
34+
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
35+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
3636
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
37-
api 'androidx.recyclerview:recyclerview:1.0.0'
38-
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
37+
api 'androidx.recyclerview:recyclerview:1.1.0'
38+
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
3939
api 'com.github.bumptech.glide:glide:4.11.0'
4040
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
4141

picker/src/main/java/pizzk/media/picker/widget/PhotoGroupView.kt

Lines changed: 68 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package pizzk.media.picker.widget
22

3+
import android.annotation.SuppressLint
34
import android.app.Activity
45
import android.content.Context
6+
import android.content.res.TypedArray
7+
import android.graphics.Rect
58
import android.net.Uri
6-
import androidx.recyclerview.widget.GridLayoutManager
7-
import androidx.recyclerview.widget.RecyclerView
89
import android.util.AttributeSet
10+
import android.view.View
911
import android.view.ViewGroup
12+
import androidx.recyclerview.widget.GridLayoutManager
13+
import androidx.recyclerview.widget.RecyclerView
1014
import pizzk.media.picker.R
1115
import pizzk.media.picker.adapter.CommonListAdapter
1216
import pizzk.media.picker.adapter.PhotoGroupAdapter
@@ -20,15 +24,20 @@ import pizzk.media.picker.view.PickChoseActivity
2024
* 选取一组照片的视图
2125
*/
2226
class PhotoGroupView : RecyclerView {
27+
private var spacing: Int = 0
2328

24-
constructor(context: Context) : super(context)
25-
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
26-
constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle)
29+
constructor(context: Context) : this(context, null)
30+
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, androidx.recyclerview.R.attr.recyclerViewStyle)
2731

28-
init {
32+
@SuppressLint("Recycle")
33+
constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {
2934
isVerticalScrollBarEnabled = false
3035
isHorizontalScrollBarEnabled = false
3136
overScrollMode = OVER_SCROLL_NEVER
37+
val attrId = R.styleable.PhotoGroupView
38+
val ta: TypedArray = context.obtainStyledAttributes(attrs, attrId) ?: return
39+
spacing = ta.getDimensionPixelOffset(R.styleable.PhotoGroupView_space, spacing)
40+
ta.recycle()
3241
}
3342

3443
private val choiceList: List<String> = listOf(
@@ -41,38 +50,49 @@ class PhotoGroupView : RecyclerView {
4150
readOnly: Boolean,
4251
appendText: String = "",
4352
changed: (PhotoGroupAdapter, Int) -> Unit = { _, _ -> }) {
44-
val manager = object : GridLayoutManager(context, special.column) {
45-
override fun isAutoMeasureEnabled(): Boolean = true
46-
}
47-
this.layoutManager = manager
48-
val pAdapter = PhotoGroupAdapter(context, special.fixed, special.lp)
49-
pAdapter.setReadOnly(readOnly)
50-
pAdapter.setChangeBlock(changed)
51-
pAdapter.setAppendText(appendText)
52-
if (!pAdapter.update(exists, special.limit, index = -1)) {
53-
changed(pAdapter, -1)
54-
}
55-
this.adapter = pAdapter
56-
//配置Adapter
57-
pAdapter.setTapBlock { _, index ->
58-
val el: PhotoItem = pAdapter.getList()[index]
59-
if (el.path.isEmpty()) {
60-
if (pAdapter.isReadOnly()) return@setTapBlock
61-
//选择图片
62-
val selects: List<String> = if (pAdapter.isAppend) pAdapter.selectPaths() else emptyList()
63-
PickChoseActivity.show(special.activity, choiceList) { key ->
64-
showPickPhoto(special.activity, key, selects, special.limit, pAdapter, index, special.crop)
53+
post {
54+
val vWidth = measuredWidth - paddingStart - paddingEnd
55+
val minWidth = context.resources.getDimensionPixelOffset(R.dimen.pick_photo_min_size)
56+
val lp: ViewGroup.LayoutParams = ViewGroup.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT)
57+
do {
58+
lp.width = (vWidth - (special.column - 1) * spacing) / special.column
59+
if (lp.width >= minWidth || special.column <= 1) break
60+
special.column -= 1
61+
} while (true)
62+
val manager = object : GridLayoutManager(context, special.column) {
63+
override fun isAutoMeasureEnabled(): Boolean = true
64+
}
65+
this.layoutManager = manager
66+
addItemDecoration(GridSpacingItemDecoration(special.column, spacing))
67+
val pAdapter = PhotoGroupAdapter(context, special.fixed, lp)
68+
pAdapter.setReadOnly(readOnly)
69+
pAdapter.setChangeBlock(changed)
70+
pAdapter.setAppendText(appendText)
71+
if (!pAdapter.update(exists, special.limit, index = -1)) {
72+
changed(pAdapter, -1)
73+
}
74+
this.adapter = pAdapter
75+
//配置Adapter
76+
pAdapter.setTapBlock { _, index ->
77+
val el: PhotoItem = pAdapter.getList()[index]
78+
if (el.path.isEmpty()) {
79+
if (pAdapter.isReadOnly()) return@setTapBlock
80+
//选择图片
81+
val selects: List<String> = if (pAdapter.isAppend) pAdapter.selectPaths() else emptyList()
82+
PickChoseActivity.show(special.activity, choiceList) { key ->
83+
showPickPhoto(special.activity, key, selects, special.limit, pAdapter, index, special.crop)
84+
}
85+
} else {
86+
//预览
87+
val selects: List<String> = if (pAdapter.isAppend) pAdapter.selectPaths() else arrayListOf(el.path)
88+
showPreview(special.activity, selects, if (pAdapter.isAppend) index else 0)
6589
}
66-
} else {
67-
//预览
68-
val selects: List<String> = if (pAdapter.isAppend) pAdapter.selectPaths() else arrayListOf(el.path)
69-
showPreview(special.activity, selects, if (pAdapter.isAppend) index else 0)
7090
}
71-
}
72-
pAdapter.setTapChildBlock { _, _, index, what ->
73-
if (CommonListAdapter.WHAT0 != what) return@setTapChildBlock
74-
//移除图片
75-
pAdapter.delete(index)
91+
pAdapter.setTapChildBlock { _, _, index, what ->
92+
if (CommonListAdapter.WHAT0 != what) return@setTapChildBlock
93+
//移除图片
94+
pAdapter.delete(index)
95+
}
7696
}
7797
}
7898

@@ -136,10 +156,21 @@ class PhotoGroupView : RecyclerView {
136156
//指定参数
137157
class Special(
138158
var activity: Activity,
139-
var lp: ViewGroup.LayoutParams,
140159
var limit: Int = 1,
141160
var column: Int = 4,
142161
var fixed: MutableList<PhotoItem>? = null,
143162
var crop: CropParams? = null
144163
)
164+
165+
internal class GridSpacingItemDecoration(private val spanCount: Int, private val spacing: Int) : ItemDecoration() {
166+
167+
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: State) {
168+
val position = parent.getChildAdapterPosition(view)
169+
val column = position % spanCount
170+
outRect.left = column * spacing / spanCount
171+
outRect.right = spacing - (column + 1) * spacing / spanCount
172+
if (position < spanCount) return
173+
outRect.top = spacing
174+
}
175+
}
145176
}

picker/src/main/res/layout/pick_photo_list_item.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
app:layout_constraintEnd_toEndOf="parent"
2424
app:layout_constraintStart_toStartOf="parent"
2525
app:layout_constraintTop_toTopOf="parent"
26-
tools:ignore="UnusedAttribute" />
26+
tools:ignore="UnusedAttribute"
27+
tools:visibility="visible" />
2728

2829
<ImageView
2930
android:id="@+id/imgTarget"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<declare-styleable name="PhotoGroupView">
4+
<attr name="space" format="dimension" />
5+
</declare-styleable>
6+
</resources>

0 commit comments

Comments
 (0)