-
-
Save aqua30/b7da69fc8d78c0b117a1fb6dd5bc1d00 to your computer and use it in GitHub Desktop.
<?xml version="1.0" encoding="utf-8"?> | |
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:fillViewport="true" | |
xmlns:app="http://schemas.android.com/apk/res-auto"> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"> | |
<com.aqua30.learningproject.AdjustingViewPager | |
android:id="@+id/view_pager" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<ImageView | |
android:id="@+id/iv_heart" | |
android:layout_width="@dimen/width_action_icon" | |
android:layout_height="@dimen/height_action_icon" | |
app:layout_constraintStart_toStartOf="parent" | |
android:layout_marginTop="@dimen/margin_16" | |
android:layout_marginStart="@dimen/margin_16" | |
android:src="@drawable/ic_heart" | |
app:layout_constraintTop_toBottomOf="@id/view_pager" /> | |
<ImageView | |
android:id="@+id/iv_comment" | |
android:layout_width="@dimen/width_action_icon" | |
android:layout_height="@dimen/height_action_icon" | |
android:src="@drawable/ic_comment" | |
android:layout_marginStart="@dimen/margin_24" | |
app:layout_constraintStart_toEndOf="@id/iv_heart" | |
app:layout_constraintTop_toTopOf="@id/iv_heart" /> | |
<ImageView | |
android:id="@+id/iv_share" | |
android:layout_width="@dimen/width_action_icon" | |
android:layout_height="@dimen/height_action_icon" | |
android:src="@drawable/ic_share" | |
android:layout_marginStart="@dimen/margin_24" | |
app:layout_constraintStart_toEndOf="@id/iv_comment" | |
app:layout_constraintTop_toTopOf="@id/iv_heart" /> | |
<TextView | |
android:id="@+id/tv_actions_count" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
app:layout_constraintStart_toStartOf="@id/iv_heart" | |
app:layout_constraintTop_toBottomOf="@id/iv_heart" | |
android:layout_marginTop="@dimen/margin_16" | |
android:text="@string/action_count" | |
android:textColor="#95a5a6" | |
android:textSize="@dimen/text_size_12" /> | |
<TextView | |
android:id="@+id/tv_description" | |
android:layout_width="0dp" | |
android:layout_height="0dp" | |
app:layout_constraintStart_toStartOf="@id/iv_heart" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/tv_actions_count" | |
app:layout_constraintBottom_toBottomOf="parent" | |
android:layout_marginEnd="@dimen/margin_16" | |
android:layout_marginTop="@dimen/margin_16" | |
android:text="@string/description" | |
android:textColor="#000000" | |
android:textSize="@dimen/text_size_16" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
</ScrollView> |
package com.aqua30.learningproject | |
import android.content.Context | |
import android.util.AttributeSet | |
import android.util.Log | |
import android.view.View | |
import android.view.View.MeasureSpec | |
import androidx.viewpager.widget.ViewPager | |
class AdjustingViewPager: ViewPager { | |
private lateinit var currentView: View /* current page view in focus */ | |
private val maxHeight= 480f /* maximum height that we want on screen */ | |
private val allowedHeight = convertDpToPixel(maxHeight) /* allowed height in pixel */ | |
constructor(context: Context) : super(context) | |
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) | |
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { | |
var newViewHeight = heightMeasureSpec | |
val mode = MeasureSpec.getMode(heightMeasureSpec) | |
/* until the parent has not assigned the size to the view | |
and it is either not determined or at its maximum, assign it | |
the new measurement as it comes in focus | |
*/ | |
if (mode == MeasureSpec.UNSPECIFIED || mode == MeasureSpec.AT_MOST) { | |
super.onMeasure(widthMeasureSpec, heightMeasureSpec) | |
if (currentView == null) { | |
super.onMeasure(widthMeasureSpec, heightMeasureSpec) | |
return | |
} | |
try { | |
/* measuring the current dimensions */ | |
currentView.measure( | |
widthMeasureSpec, MeasureSpec.makeMeasureSpec( | |
0, | |
MeasureSpec.UNSPECIFIED | |
) | |
) | |
var currentViewHeight = currentView.measuredHeight | |
/* | |
if the current view height is greater than allowed height then | |
set it to allowed height | |
*/ | |
if (currentViewHeight > allowedHeight) { | |
currentViewHeight = allowedHeight.toInt() | |
} | |
newViewHeight = MeasureSpec.makeMeasureSpec(currentViewHeight, MeasureSpec.EXACTLY) | |
} catch (e: NullPointerException) { | |
Log.e(AdjustingViewPager::class.simpleName, ": " + e.message) | |
} | |
} | |
super.onMeasure(widthMeasureSpec, newViewHeight) | |
} | |
fun measureCurrentView(view: View) { | |
this.currentView = view | |
requestLayout() | |
} | |
private fun convertDpToPixel(dp: Float): Float { | |
val metrics = context.resources.displayMetrics | |
return dp * (metrics.densityDpi / 160f) | |
} | |
} |
package com.aqua30.learningproject | |
import android.content.Context | |
import android.view.LayoutInflater | |
import android.view.View | |
import android.view.ViewGroup | |
import android.widget.ImageView | |
import androidx.viewpager.widget.PagerAdapter | |
import com.bumptech.glide.Glide | |
class ImagePagerAdapter: PagerAdapter { | |
var imagesList: List<Int>? = null | |
var context: Context? = null | |
var currentPosition = -1 | |
constructor(context: Context, imagesList: List<Int>): super() { | |
this.imagesList = imagesList | |
this.context = context | |
} | |
override fun getCount(): Int { | |
return imagesList?.size!! | |
} | |
override fun isViewFromObject(view: View, `object`: Any): Boolean { | |
return view == `object` | |
} | |
override fun instantiateItem(container: ViewGroup, position: Int): Any { | |
val view = LayoutInflater.from(context).inflate(R.layout.view_item, container, false) | |
val imageView: ImageView = view.findViewById(R.id.iv_item) | |
container.addView(view) | |
Glide.with(context!!) | |
.load(imagesList?.get(position)) | |
.into(imageView) | |
return view | |
} | |
override fun setPrimaryItem(container: ViewGroup, position: Int, `object`: Any) { | |
super.setPrimaryItem(container, position, `object`) | |
if (container !is AdjustingViewPager) | |
return | |
if (position != currentPosition) { | |
val viewPager: AdjustingViewPager = container | |
currentPosition = position; | |
viewPager.measureCurrentView(`object` as View) | |
} | |
} | |
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) { | |
container.removeView(`object` as View) | |
} | |
} |
package com.aqua30.learningproject | |
import android.os.Bundle | |
import androidx.appcompat.app.AppCompatActivity | |
class MainActivity : AppCompatActivity() { | |
lateinit var viewPager : AdjustingViewPager | |
lateinit var imageAdapter: ImagePagerAdapter | |
private val imagesList: List<Int> = listOf( | |
R.drawable.img_1, | |
R.drawable.img_2, | |
R.drawable.img_3 | |
) | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContentView(R.layout.activity_main) | |
viewPager = findViewById(R.id.view_pager) | |
imageAdapter = ImagePagerAdapter(this, imagesList) | |
viewPager.adapter = imageAdapter | |
} | |
} |
<?xml version="1.0" encoding="utf-8"?> | |
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:maxHeight="430dp"> | |
<ImageView | |
android:id="@+id/iv_item" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content"/> | |
</FrameLayout> |
@kryanod This is not auto-migrated code from java. I wrote it in kotlin.
Let me know what issues you're facing.
For the point 1, are you calling viewPager.measureCurrentView(
object as View)
because otherwise you'll get currentView cannot be null
For point 2, as I'm learning kotlin so i used the defaults.
For point 3, please provide exact error you get.
Ah OK sorry, I misunderstood the whole thing then. Let me clarify my points though.
1 - your property is a lateinit var and has a type of View, i.e. it can never be null. This means that the null check at AdjustingViewPager:28 can never return true
3 - It's just a convenience thing. You can declare the whole class as
class ImagePagerAdapter(private val context: Context, private val imagesList: List<Int>)
and get rid of an extra constructor and the first two vars
Agreed @kryanod. Will update this.
This code has clearly been auto-migrated from Java and has some issues:
object
in ImagePagerAdapter