reduced status list item child view count
This commit is contained in:
parent
719794778d
commit
163cc2f88e
|
@ -76,8 +76,10 @@ install:
|
||||||
before_script:
|
before_script:
|
||||||
# Validate if patches work
|
# Validate if patches work
|
||||||
- patch --dry-run -d twidere < twidere/patches/remove_closed_source_dependencies.patch
|
- patch --dry-run -d twidere < twidere/patches/remove_closed_source_dependencies.patch
|
||||||
|
# Validate if Google components fetched successfully
|
||||||
|
- test -f twidere/src/google/AndroidManifest.xml
|
||||||
|
|
||||||
script: GRADLE_OPTS="-Dkotlin.incremental=false" ./gradlew build --no-daemon --stacktrace
|
script: ./gradlew build --no-daemon --stacktrace
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
provider: releases
|
provider: releases
|
||||||
|
|
|
@ -20,22 +20,9 @@
|
||||||
package org.mariotaku.twidere.adapter
|
package org.mariotaku.twidere.adapter
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.TextView
|
|
||||||
import com.bumptech.glide.RequestManager
|
import com.bumptech.glide.RequestManager
|
||||||
import com.commonsware.cwac.layouts.AspectLockedFrameLayout
|
|
||||||
import org.mariotaku.twidere.R
|
import org.mariotaku.twidere.R
|
||||||
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter
|
|
||||||
import org.mariotaku.twidere.extension.loadProfileImage
|
|
||||||
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable
|
|
||||||
import org.mariotaku.twidere.model.ParcelableMedia
|
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus
|
|
||||||
import org.mariotaku.twidere.model.UserKey
|
|
||||||
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
|
|
||||||
import org.mariotaku.twidere.view.MediaPreviewImageView
|
|
||||||
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,7 +34,7 @@ class StaggeredGridParcelableStatusesAdapter(
|
||||||
) : ParcelableStatusesAdapter(context, requestManager) {
|
) : ParcelableStatusesAdapter(context, requestManager) {
|
||||||
|
|
||||||
override val progressViewIds: IntArray
|
override val progressViewIds: IntArray
|
||||||
get() = intArrayOf(R.id.media_image_progress)
|
get() = intArrayOf(R.id.mediaImageProgress)
|
||||||
|
|
||||||
override fun onCreateStatusViewHolder(parent: ViewGroup): IStatusViewHolder {
|
override fun onCreateStatusViewHolder(parent: ViewGroup): IStatusViewHolder {
|
||||||
val view = inflater.inflate(R.layout.adapter_item_media_status, parent, false)
|
val view = inflater.inflate(R.layout.adapter_item_media_status, parent, false)
|
||||||
|
@ -57,104 +44,4 @@ class StaggeredGridParcelableStatusesAdapter(
|
||||||
return holder
|
return holder
|
||||||
}
|
}
|
||||||
|
|
||||||
class MediaStatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View) : RecyclerView.ViewHolder(itemView), IStatusViewHolder, View.OnClickListener, View.OnLongClickListener {
|
|
||||||
private val aspectRatioSource = SimpleAspectRatioSource().apply {
|
|
||||||
setSize(100, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val mediaImageContainer: AspectLockedFrameLayout
|
|
||||||
private val mediaImageView: MediaPreviewImageView
|
|
||||||
override val profileImageView: ImageView
|
|
||||||
private val mediaTextView: TextView
|
|
||||||
private var listener: IStatusViewHolder.StatusClickListener? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
mediaImageContainer = itemView.findViewById(R.id.media_image_container) as AspectLockedFrameLayout
|
|
||||||
mediaImageContainer.setAspectRatioSource(aspectRatioSource)
|
|
||||||
mediaImageView = itemView.findViewById(R.id.media_image) as MediaPreviewImageView
|
|
||||||
profileImageView = itemView.findViewById(R.id.media_profile_image) as ImageView
|
|
||||||
mediaTextView = itemView.findViewById(R.id.media_text) as TextView
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun displayStatus(status: ParcelableStatus, displayInReplyTo: Boolean,
|
|
||||||
displayExtraType: Boolean, displayPinned: Boolean) {
|
|
||||||
val media = status.media ?: return
|
|
||||||
if (media.isEmpty()) return
|
|
||||||
val firstMedia = media[0]
|
|
||||||
mediaTextView.text = status.text_unescaped
|
|
||||||
if (firstMedia.width > 0 && firstMedia.height > 0) {
|
|
||||||
aspectRatioSource.setSize(firstMedia.width, firstMedia.height)
|
|
||||||
} else {
|
|
||||||
aspectRatioSource.setSize(100, 100)
|
|
||||||
}
|
|
||||||
mediaImageContainer.tag = firstMedia
|
|
||||||
mediaImageContainer.requestLayout()
|
|
||||||
|
|
||||||
mediaImageView.setHasPlayIcon(ParcelableMediaUtils.hasPlayIcon(firstMedia.type))
|
|
||||||
val context = itemView.context
|
|
||||||
adapter.requestManager.loadProfileImage(context, status).into(profileImageView)
|
|
||||||
// TODO image loaded event and credentials
|
|
||||||
adapter.requestManager.load(firstMedia.preview_url).into(mediaImageView)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val profileTypeView: ImageView?
|
|
||||||
get() = null
|
|
||||||
|
|
||||||
override fun onClick(v: View) {
|
|
||||||
when (v.id) {
|
|
||||||
R.id.itemContent -> {
|
|
||||||
listener?.onStatusClick(this, layoutPosition)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLongClick(v: View): Boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMediaClick(view: View, media: ParcelableMedia, accountKey: UserKey?, id: Long) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setStatusClickListener(listener: IStatusViewHolder.StatusClickListener?) {
|
|
||||||
this.listener = listener
|
|
||||||
itemView.findViewById(R.id.itemContent).setOnClickListener(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setTextSize(textSize: Float) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun playLikeAnimation(listener: LikeAnimationDrawable.OnLikedListener) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setOnClickListeners() {
|
|
||||||
setStatusClickListener(adapter.statusClickListener)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setupViewOptions() {
|
|
||||||
setTextSize(adapter.textSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class SimpleAspectRatioSource : AspectLockedFrameLayout.AspectRatioSource {
|
|
||||||
private var width: Int = 0
|
|
||||||
private var height: Int = 0
|
|
||||||
|
|
||||||
override fun getWidth(): Int {
|
|
||||||
return width
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getHeight(): Int {
|
|
||||||
return height
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSize(width: Int, height: Int) {
|
|
||||||
this.width = width
|
|
||||||
this.height = height
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
import jp.wasabeef.glide.transformations.CropCircleTransformation
|
import jp.wasabeef.glide.transformations.CropCircleTransformation
|
||||||
import org.mariotaku.twidere.R
|
import org.mariotaku.twidere.R
|
||||||
import org.mariotaku.twidere.annotation.ImageShapeStyle
|
import org.mariotaku.twidere.annotation.ImageShapeStyle
|
||||||
|
import org.mariotaku.twidere.extension.model.getBestProfileBanner
|
||||||
import org.mariotaku.twidere.extension.model.user
|
import org.mariotaku.twidere.extension.model.user
|
||||||
import org.mariotaku.twidere.model.*
|
import org.mariotaku.twidere.model.*
|
||||||
import org.mariotaku.twidere.util.Utils
|
import org.mariotaku.twidere.util.Utils
|
||||||
|
@ -100,6 +101,10 @@ fun RequestManager.loadOriginalProfileImage(context: Context, user: ParcelableUs
|
||||||
return configureLoadProfileImage(context, shapeStyle) { load(original) }
|
return configureLoadProfileImage(context, shapeStyle) { load(original) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun RequestManager.loadProfileBanner(context: Context, user: ParcelableUser, width: Int): DrawableTypeRequest<String?> {
|
||||||
|
return load(user.getBestProfileBanner(width))
|
||||||
|
}
|
||||||
|
|
||||||
internal inline fun <T> configureLoadProfileImage(context: Context, shapeStyle: Int,
|
internal inline fun <T> configureLoadProfileImage(context: Context, shapeStyle: Int,
|
||||||
create: () -> DrawableTypeRequest<T>): DrawableRequestBuilder<T> {
|
create: () -> DrawableTypeRequest<T>): DrawableRequestBuilder<T> {
|
||||||
val builder = create()
|
val builder = create()
|
||||||
|
|
|
@ -31,6 +31,7 @@ import android.support.v7.widget.LinearLayoutManager
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
import android.support.v7.widget.RecyclerView.OnScrollListener
|
import android.support.v7.widget.RecyclerView.OnScrollListener
|
||||||
import android.view.*
|
import android.view.*
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
import com.squareup.otto.Subscribe
|
import com.squareup.otto.Subscribe
|
||||||
import edu.tsinghua.hotmobi.HotMobiLogger
|
import edu.tsinghua.hotmobi.HotMobiLogger
|
||||||
import edu.tsinghua.hotmobi.model.MediaEvent
|
import edu.tsinghua.hotmobi.model.MediaEvent
|
||||||
|
@ -101,7 +102,7 @@ abstract class AbsActivitiesFragment protected constructor() :
|
||||||
registerForContextMenu(recyclerView)
|
registerForContextMenu(recyclerView)
|
||||||
navigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter,
|
navigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter,
|
||||||
this)
|
this)
|
||||||
pauseOnScrollListener = PauseRecyclerViewOnScrollListener(false, true)
|
pauseOnScrollListener = PauseRecyclerViewOnScrollListener(false, true, Glide.with(this))
|
||||||
|
|
||||||
val loaderArgs = Bundle(arguments)
|
val loaderArgs = Bundle(arguments)
|
||||||
loaderArgs.putBoolean(EXTRA_FROM_USER, true)
|
loaderArgs.putBoolean(EXTRA_FROM_USER, true)
|
||||||
|
|
|
@ -32,6 +32,7 @@ import android.support.v7.widget.LinearLayoutManager
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
import android.support.v7.widget.RecyclerView.OnScrollListener
|
import android.support.v7.widget.RecyclerView.OnScrollListener
|
||||||
import android.view.*
|
import android.view.*
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
import com.squareup.otto.Subscribe
|
import com.squareup.otto.Subscribe
|
||||||
import edu.tsinghua.hotmobi.HotMobiLogger
|
import edu.tsinghua.hotmobi.HotMobiLogger
|
||||||
import edu.tsinghua.hotmobi.model.MediaEvent
|
import edu.tsinghua.hotmobi.model.MediaEvent
|
||||||
|
@ -128,7 +129,7 @@ abstract class AbsStatusesFragment : AbsContentListRecyclerViewFragment<Parcelab
|
||||||
adapter.statusClickListener = this
|
adapter.statusClickListener = this
|
||||||
registerForContextMenu(recyclerView)
|
registerForContextMenu(recyclerView)
|
||||||
navigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter, this)
|
navigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter, this)
|
||||||
pauseOnScrollListener = PauseRecyclerViewOnScrollListener(false, true)
|
pauseOnScrollListener = PauseRecyclerViewOnScrollListener(false, true, Glide.with(this))
|
||||||
|
|
||||||
if (shouldInitLoader) {
|
if (shouldInitLoader) {
|
||||||
initLoaderIfNeeded()
|
initLoaderIfNeeded()
|
||||||
|
|
|
@ -71,6 +71,7 @@ import org.mariotaku.twidere.annotation.Referral
|
||||||
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.*
|
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.*
|
||||||
import org.mariotaku.twidere.constant.extraFeaturesNoticeVersionKey
|
import org.mariotaku.twidere.constant.extraFeaturesNoticeVersionKey
|
||||||
import org.mariotaku.twidere.constant.profileImageStyleKey
|
import org.mariotaku.twidere.constant.profileImageStyleKey
|
||||||
|
import org.mariotaku.twidere.extension.loadProfileBanner
|
||||||
import org.mariotaku.twidere.extension.loadProfileImage
|
import org.mariotaku.twidere.extension.loadProfileImage
|
||||||
import org.mariotaku.twidere.extension.model.setActivated
|
import org.mariotaku.twidere.extension.model.setActivated
|
||||||
import org.mariotaku.twidere.fragment.AccountsDashboardFragment.AccountsInfo
|
import org.mariotaku.twidere.fragment.AccountsDashboardFragment.AccountsInfo
|
||||||
|
@ -80,10 +81,8 @@ import org.mariotaku.twidere.model.AccountDetails
|
||||||
import org.mariotaku.twidere.model.SupportTabSpec
|
import org.mariotaku.twidere.model.SupportTabSpec
|
||||||
import org.mariotaku.twidere.model.UserKey
|
import org.mariotaku.twidere.model.UserKey
|
||||||
import org.mariotaku.twidere.model.util.AccountUtils
|
import org.mariotaku.twidere.model.util.AccountUtils
|
||||||
import org.mariotaku.twidere.model.util.ParcelableUserUtils
|
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
|
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
|
||||||
import org.mariotaku.twidere.util.*
|
import org.mariotaku.twidere.util.*
|
||||||
import org.mariotaku.twidere.util.InternalTwitterContentUtils.getBestBannerUrl
|
|
||||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
|
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
|
||||||
import org.mariotaku.twidere.view.ShapedImageView
|
import org.mariotaku.twidere.view.ShapedImageView
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
@ -502,8 +501,8 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks<AccountsInfo>,
|
||||||
val defWidth = res.displayMetrics.widthPixels
|
val defWidth = res.displayMetrics.widthPixels
|
||||||
val width = if (bannerWidth > 0) bannerWidth else defWidth
|
val width = if (bannerWidth > 0) bannerWidth else defWidth
|
||||||
val bannerView = accountProfileBanner.nextView as ImageView
|
val bannerView = accountProfileBanner.nextView as ImageView
|
||||||
val url = getBestBannerUrl(ParcelableUserUtils.getProfileBannerUrl(account.user), width)
|
|
||||||
Glide.with(this).load(url).into(bannerView)
|
Glide.with(this).loadProfileBanner(context, account.user, width).into(bannerView)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun displayCurrentAccount(profileImageSnapshot: Drawable?) {
|
private fun displayCurrentAccount(profileImageSnapshot: Drawable?) {
|
||||||
|
|
|
@ -105,7 +105,7 @@ import org.mariotaku.twidere.constant.newDocumentApiKey
|
||||||
import org.mariotaku.twidere.constant.profileImageStyleKey
|
import org.mariotaku.twidere.constant.profileImageStyleKey
|
||||||
import org.mariotaku.twidere.extension.applyTheme
|
import org.mariotaku.twidere.extension.applyTheme
|
||||||
import org.mariotaku.twidere.extension.loadOriginalProfileImage
|
import org.mariotaku.twidere.extension.loadOriginalProfileImage
|
||||||
import org.mariotaku.twidere.extension.loadProfileImage
|
import org.mariotaku.twidere.extension.loadProfileBanner
|
||||||
import org.mariotaku.twidere.extension.model.applyTo
|
import org.mariotaku.twidere.extension.model.applyTo
|
||||||
import org.mariotaku.twidere.fragment.AbsStatusesFragment.StatusesFragmentDelegate
|
import org.mariotaku.twidere.fragment.AbsStatusesFragment.StatusesFragmentDelegate
|
||||||
import org.mariotaku.twidere.fragment.UserTimelineFragment.UserTimelineFragmentDelegate
|
import org.mariotaku.twidere.fragment.UserTimelineFragment.UserTimelineFragmentDelegate
|
||||||
|
@ -521,9 +521,8 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
|
||||||
}
|
}
|
||||||
val defWidth = resources.displayMetrics.widthPixels
|
val defWidth = resources.displayMetrics.widthPixels
|
||||||
val width = if (bannerWidth > 0) bannerWidth else defWidth
|
val width = if (bannerWidth > 0) bannerWidth else defWidth
|
||||||
val bannerUrl = getBestBannerUrl(ParcelableUserUtils.getProfileBannerUrl(user), width)
|
|
||||||
val requestManager = Glide.with(this)
|
val requestManager = Glide.with(this)
|
||||||
requestManager.load(bannerUrl).into(profileBanner)
|
requestManager.loadProfileBanner(context, user, width).into(profileBanner)
|
||||||
requestManager.loadOriginalProfileImage(context, user, profileImage.style).into(profileImage)
|
requestManager.loadOriginalProfileImage(context, user, profileImage.style).into(profileImage)
|
||||||
val relationship = relationship
|
val relationship = relationship
|
||||||
if (relationship == null) {
|
if (relationship == null) {
|
||||||
|
|
|
@ -50,8 +50,8 @@ import org.mariotaku.twidere.R
|
||||||
import org.mariotaku.twidere.TwidereConstants.*
|
import org.mariotaku.twidere.TwidereConstants.*
|
||||||
import org.mariotaku.twidere.activity.ColorPickerDialogActivity
|
import org.mariotaku.twidere.activity.ColorPickerDialogActivity
|
||||||
import org.mariotaku.twidere.activity.ThemedMediaPickerActivity
|
import org.mariotaku.twidere.activity.ThemedMediaPickerActivity
|
||||||
|
import org.mariotaku.twidere.extension.loadProfileBanner
|
||||||
import org.mariotaku.twidere.extension.loadProfileImage
|
import org.mariotaku.twidere.extension.loadProfileImage
|
||||||
import org.mariotaku.twidere.extension.model.getBestProfileBanner
|
|
||||||
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
|
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
|
||||||
import org.mariotaku.twidere.loader.ParcelableUserLoader
|
import org.mariotaku.twidere.loader.ParcelableUserLoader
|
||||||
import org.mariotaku.twidere.model.AccountDetails
|
import org.mariotaku.twidere.model.AccountDetails
|
||||||
|
@ -290,7 +290,7 @@ class UserProfileEditorFragment : BaseFragment(), OnSizeChangedListener, TextWat
|
||||||
editUrl.setText(if (isEmpty(user.url_expanded)) user.url else user.url_expanded)
|
editUrl.setText(if (isEmpty(user.url_expanded)) user.url else user.url_expanded)
|
||||||
|
|
||||||
Glide.with(this).loadProfileImage(context, user).into(profileImage)
|
Glide.with(this).loadProfileImage(context, user).into(profileImage)
|
||||||
Glide.with(this).load(user.getBestProfileBanner(resources.displayMetrics.widthPixels)).into(profileBanner)
|
Glide.with(this).loadProfileBanner(context, user, resources.displayMetrics.widthPixels).into(profileBanner)
|
||||||
Glide.with(this).load(user.profile_background_url).into(profileBackground)
|
Glide.with(this).load(user.profile_background_url).into(profileBackground)
|
||||||
|
|
||||||
linkColor.color = user.link_color
|
linkColor.color = user.link_color
|
||||||
|
|
|
@ -20,22 +20,27 @@
|
||||||
package org.mariotaku.twidere.util.imageloader
|
package org.mariotaku.twidere.util.imageloader
|
||||||
|
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.RequestManager
|
||||||
|
|
||||||
class PauseRecyclerViewOnScrollListener(
|
class PauseRecyclerViewOnScrollListener(
|
||||||
private val pauseOnScroll: Boolean,
|
private val pauseOnScroll: Boolean,
|
||||||
private val pauseOnFling: Boolean
|
private val pauseOnFling: Boolean,
|
||||||
|
private val requestManager: RequestManager
|
||||||
) : RecyclerView.OnScrollListener() {
|
) : RecyclerView.OnScrollListener() {
|
||||||
|
|
||||||
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
|
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
|
||||||
when (newState) {
|
when (newState) {
|
||||||
RecyclerView.SCROLL_STATE_IDLE -> {
|
RecyclerView.SCROLL_STATE_IDLE -> {
|
||||||
// TODO resume media load
|
if (!requestManager.isPaused) return
|
||||||
|
requestManager.resumeRequests()
|
||||||
}
|
}
|
||||||
RecyclerView.SCROLL_STATE_DRAGGING -> if (this.pauseOnScroll) {
|
RecyclerView.SCROLL_STATE_DRAGGING -> if (this.pauseOnScroll) {
|
||||||
// TODO pause media load
|
if (requestManager.isPaused) return
|
||||||
|
requestManager.pauseRequests()
|
||||||
}
|
}
|
||||||
RecyclerView.SCROLL_STATE_SETTLING -> if (this.pauseOnFling) {
|
RecyclerView.SCROLL_STATE_SETTLING -> if (this.pauseOnFling) {
|
||||||
// TODO pause media load
|
if (requestManager.isPaused) return
|
||||||
|
requestManager.pauseRequests()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,15 +58,12 @@ class CardMediaContainer(context: Context, attrs: AttributeSet? = null) : ViewGr
|
||||||
fun displayMedia(vararg imageRes: Int) {
|
fun displayMedia(vararg imageRes: Int) {
|
||||||
val k = imageRes.size
|
val k = imageRes.size
|
||||||
for (i in 0 until childCount) {
|
for (i in 0 until childCount) {
|
||||||
val child = getChildAt(i)
|
val child = getChildAt(i) as ImageView
|
||||||
val imageView = child.findViewById(R.id.mediaPreview) as ImageView
|
|
||||||
val progress = child.findViewById(R.id.media_preview_progress)
|
|
||||||
progress.visibility = View.GONE
|
|
||||||
if (i < k) {
|
if (i < k) {
|
||||||
imageView.setImageResource(imageRes[i])
|
child.setImageResource(imageRes[i])
|
||||||
child.visibility = View.VISIBLE
|
child.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
imageView.setImageDrawable(null)
|
child.setImageDrawable(null)
|
||||||
child.visibility = View.GONE
|
child.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,17 +82,16 @@ class CardMediaContainer(context: Context, attrs: AttributeSet? = null) : ViewGr
|
||||||
val clickListener = ImageGridClickListener(mediaClickListener, accountId, extraId)
|
val clickListener = ImageGridClickListener(mediaClickListener, accountId, extraId)
|
||||||
val mediaSize = media.size
|
val mediaSize = media.size
|
||||||
for (i in 0 until childCount) {
|
for (i in 0 until childCount) {
|
||||||
val child = getChildAt(i)
|
val child = getChildAt(i) as ImageView
|
||||||
if (mediaClickListener != null) {
|
if (mediaClickListener != null) {
|
||||||
child.setOnClickListener(clickListener)
|
child.setOnClickListener(clickListener)
|
||||||
}
|
}
|
||||||
val imageView = child.findViewById(R.id.mediaPreview) as ImageView
|
|
||||||
when (style) {
|
when (style) {
|
||||||
PreviewStyle.REAL_SIZE, PreviewStyle.CROP -> {
|
PreviewStyle.REAL_SIZE, PreviewStyle.CROP -> {
|
||||||
imageView.scaleType = ScaleType.CENTER_CROP
|
child.scaleType = ScaleType.CENTER_CROP
|
||||||
}
|
}
|
||||||
PreviewStyle.SCALE -> {
|
PreviewStyle.SCALE -> {
|
||||||
imageView.scaleType = ScaleType.FIT_CENTER
|
child.scaleType = ScaleType.FIT_CENTER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i < mediaSize) {
|
if (i < mediaSize) {
|
||||||
|
@ -106,16 +102,16 @@ class CardMediaContainer(context: Context, attrs: AttributeSet? = null) : ViewGr
|
||||||
item.media_url
|
item.media_url
|
||||||
}
|
}
|
||||||
if (withCredentials) {
|
if (withCredentials) {
|
||||||
requestManager.load(url).into(imageView)
|
requestManager.load(url).into(child)
|
||||||
// TODO handle load progress w/ authentication
|
// TODO handle load progress w/ authentication
|
||||||
// loader.displayPreviewImageWithCredentials(imageView, url, accountId, loadingHandler, video)
|
// loader.displayPreviewImageWithCredentials(imageView, url, accountId, loadingHandler, video)
|
||||||
} else {
|
} else {
|
||||||
requestManager.load(url).into(imageView)
|
requestManager.load(url).into(child)
|
||||||
// TODO handle load progress
|
// TODO handle load progress
|
||||||
// loader.displayPreviewImage(imageView, url, loadingHandler, video)
|
// loader.displayPreviewImage(imageView, url, loadingHandler, video)
|
||||||
}
|
}
|
||||||
if (imageView is MediaPreviewImageView) {
|
if (child is MediaPreviewImageView) {
|
||||||
imageView.setHasPlayIcon(ParcelableMediaUtils.hasPlayIcon(item.type))
|
child.setHasPlayIcon(ParcelableMediaUtils.hasPlayIcon(item.type))
|
||||||
}
|
}
|
||||||
if (item.alt_text.isNullOrEmpty()) {
|
if (item.alt_text.isNullOrEmpty()) {
|
||||||
child.contentDescription = context.getString(R.string.media)
|
child.contentDescription = context.getString(R.string.media)
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* Twidere - Twitter client for Android
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.mariotaku.twidere.adapter
|
||||||
|
|
||||||
|
import android.support.v7.widget.RecyclerView
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.ImageView
|
||||||
|
import com.commonsware.cwac.layouts.AspectLockedFrameLayout
|
||||||
|
import kotlinx.android.synthetic.main.adapter_item_media_status.view.*
|
||||||
|
import org.mariotaku.twidere.R
|
||||||
|
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter
|
||||||
|
import org.mariotaku.twidere.extension.loadProfileImage
|
||||||
|
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable
|
||||||
|
import org.mariotaku.twidere.model.ParcelableMedia
|
||||||
|
import org.mariotaku.twidere.model.ParcelableStatus
|
||||||
|
import org.mariotaku.twidere.model.UserKey
|
||||||
|
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
|
||||||
|
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
||||||
|
|
||||||
|
class MediaStatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View) : RecyclerView.ViewHolder(itemView), IStatusViewHolder, View.OnClickListener, View.OnLongClickListener {
|
||||||
|
private val aspectRatioSource = SimpleAspectRatioSource().apply {
|
||||||
|
setSize(100, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val mediaImageContainer = itemView.mediaImageContainer
|
||||||
|
private val mediaImageView = itemView.mediaImage
|
||||||
|
override val profileImageView: ImageView = itemView.mediaProfileImage
|
||||||
|
private val mediaTextView = itemView.mediaText
|
||||||
|
private var listener: IStatusViewHolder.StatusClickListener? = null
|
||||||
|
|
||||||
|
override val profileTypeView: ImageView?
|
||||||
|
get() = null
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
mediaImageContainer.setAspectRatioSource(aspectRatioSource)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun displayStatus(status: ParcelableStatus, displayInReplyTo: Boolean,
|
||||||
|
displayExtraType: Boolean, displayPinned: Boolean) {
|
||||||
|
val media = status.media ?: return
|
||||||
|
if (media.isEmpty()) return
|
||||||
|
val firstMedia = media[0]
|
||||||
|
|
||||||
|
var displayEnd = -1
|
||||||
|
if (status.extras.display_text_range != null) {
|
||||||
|
displayEnd = status.extras.display_text_range!![1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayEnd >= 0) {
|
||||||
|
mediaTextView.text = status.text_unescaped.subSequence(0, displayEnd)
|
||||||
|
} else {
|
||||||
|
mediaTextView.text = status.text_unescaped
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstMedia.width > 0 && firstMedia.height > 0) {
|
||||||
|
aspectRatioSource.setSize(firstMedia.width, firstMedia.height)
|
||||||
|
} else {
|
||||||
|
aspectRatioSource.setSize(100, 100)
|
||||||
|
}
|
||||||
|
mediaImageContainer.tag = firstMedia
|
||||||
|
mediaImageContainer.requestLayout()
|
||||||
|
|
||||||
|
mediaImageView.setHasPlayIcon(ParcelableMediaUtils.hasPlayIcon(firstMedia.type))
|
||||||
|
val context = itemView.context
|
||||||
|
adapter.requestManager.loadProfileImage(context, status).into(profileImageView)
|
||||||
|
// TODO image loaded event and credentials
|
||||||
|
adapter.requestManager.load(firstMedia.preview_url).into(mediaImageView)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View) {
|
||||||
|
when (v.id) {
|
||||||
|
R.id.itemContent -> {
|
||||||
|
listener?.onStatusClick(this, layoutPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLongClick(v: View): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMediaClick(view: View, media: ParcelableMedia, accountKey: UserKey?, id: Long) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setStatusClickListener(listener: IStatusViewHolder.StatusClickListener?) {
|
||||||
|
this.listener = listener
|
||||||
|
itemView.findViewById(R.id.itemContent).setOnClickListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setTextSize(textSize: Float) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun playLikeAnimation(listener: LikeAnimationDrawable.OnLikedListener) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setOnClickListeners() {
|
||||||
|
setStatusClickListener(adapter.statusClickListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setupViewOptions() {
|
||||||
|
setTextSize(adapter.textSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class SimpleAspectRatioSource : AspectLockedFrameLayout.AspectRatioSource {
|
||||||
|
private var width: Int = 0
|
||||||
|
private var height: Int = 0
|
||||||
|
|
||||||
|
override fun getWidth(): Int {
|
||||||
|
return width
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getHeight(): Int {
|
||||||
|
return height
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setSize(width: Int, height: Int) {
|
||||||
|
this.width = width
|
||||||
|
this.height = height
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -344,7 +344,6 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
||||||
mediaPreview.visibility = View.GONE
|
mediaPreview.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var displayEnd = -1
|
var displayEnd = -1
|
||||||
if (status.extras.display_text_range != null) {
|
if (status.extras.display_text_range != null) {
|
||||||
displayEnd = status.extras.display_text_range!![1]
|
displayEnd = status.extras.display_text_range!![1]
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
android:id="@+id/itemContent"
|
android:id="@+id/itemContent"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/element_spacing_small"
|
android:layout_margin="@dimen/element_spacing_small"
|
||||||
|
@ -36,20 +37,21 @@
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.commonsware.cwac.layouts.AspectLockedFrameLayout
|
<com.commonsware.cwac.layouts.AspectLockedFrameLayout
|
||||||
android:id="@+id/media_image_container"
|
android:id="@+id/mediaImageContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<org.mariotaku.twidere.view.MediaPreviewImageView
|
<org.mariotaku.twidere.view.MediaPreviewImageView
|
||||||
android:id="@+id/media_image"
|
android:id="@+id/mediaImage"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:contentDescription="@string/media"
|
android:contentDescription="@string/media"
|
||||||
android:foregroundGravity="center"
|
android:foregroundGravity="center"
|
||||||
android:scaleType="centerCrop"/>
|
android:scaleType="centerCrop"
|
||||||
|
tools:src="@drawable/featured_graphics"/>
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/media_image_progress"
|
android:id="@+id/mediaImageProgress"
|
||||||
style="?android:progressBarStyleHorizontal"
|
style="?android:progressBarStyleHorizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -58,27 +60,33 @@
|
||||||
</com.commonsware.cwac.layouts.AspectLockedFrameLayout>
|
</com.commonsware.cwac.layouts.AspectLockedFrameLayout>
|
||||||
|
|
||||||
<org.mariotaku.twidere.view.ColorLabelRelativeLayout
|
<org.mariotaku.twidere.view.ColorLabelRelativeLayout
|
||||||
android:id="@+id/media_info_container"
|
android:id="@+id/mediaInfoContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="@dimen/element_spacing_small">
|
android:padding="@dimen/element_spacing_small">
|
||||||
|
|
||||||
<org.mariotaku.twidere.view.ProfileImageView
|
<org.mariotaku.twidere.view.ProfileImageView
|
||||||
android:id="@+id/media_profile_image"
|
android:id="@+id/mediaProfileImage"
|
||||||
style="?profileImageStyle"
|
style="?profileImageStyle"
|
||||||
android:layout_width="@dimen/element_size_small"
|
android:layout_width="@dimen/element_size_small"
|
||||||
android:layout_height="@dimen/element_size_small"/>
|
android:layout_height="@dimen/element_size_small"
|
||||||
|
tools:src="@drawable/ic_profile_image_twidere"/>
|
||||||
|
|
||||||
<org.mariotaku.twidere.view.FixedTextView
|
<org.mariotaku.twidere.view.FixedTextView
|
||||||
android:id="@+id/media_text"
|
android:id="@+id/mediaText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignTop="@+id/media_profile_image"
|
android:layout_alignTop="@+id/mediaProfileImage"
|
||||||
android:layout_marginLeft="@dimen/element_spacing_small"
|
android:layout_marginLeft="@dimen/element_spacing_small"
|
||||||
android:layout_marginStart="@dimen/element_spacing_small"
|
android:layout_marginStart="@dimen/element_spacing_small"
|
||||||
android:layout_toEndOf="@+id/media_profile_image"
|
android:layout_toEndOf="@+id/mediaProfileImage"
|
||||||
android:layout_toRightOf="@+id/media_profile_image"
|
android:layout_toRightOf="@+id/mediaProfileImage"
|
||||||
android:ellipsize="end"/>
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:minHeight="@dimen/element_size_small"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
tools:text="@string/sample_status_text"/>
|
||||||
</org.mariotaku.twidere.view.ColorLabelRelativeLayout>
|
</org.mariotaku.twidere.view.ColorLabelRelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -23,40 +23,48 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:showIn="@layout/list_item_status">
|
tools:showIn="@layout/list_item_status">
|
||||||
|
|
||||||
<com.commonsware.cwac.layouts.AspectLockedFrameLayout
|
<org.mariotaku.twidere.view.MediaPreviewImageView
|
||||||
android:id="@+id/media_preview_item_0"
|
android:id="@+id/mediaPreviewItem0"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:foreground="?selectableItemBackground">
|
android:contentDescription="@string/media"
|
||||||
|
android:foreground="?selectableItemBackground"
|
||||||
|
android:foregroundGravity="center"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:ignore="DuplicateIncludedIds"
|
||||||
|
tools:src="@drawable/featured_graphics"/>
|
||||||
|
|
||||||
<include layout="@layout/layout_card_media_preview_item"/>
|
<org.mariotaku.twidere.view.MediaPreviewImageView
|
||||||
</com.commonsware.cwac.layouts.AspectLockedFrameLayout>
|
android:id="@+id/mediaPreviewItem1"
|
||||||
|
|
||||||
<com.commonsware.cwac.layouts.AspectLockedFrameLayout
|
|
||||||
android:id="@+id/media_preview_item_1"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:foreground="?selectableItemBackground">
|
android:contentDescription="@string/media"
|
||||||
|
android:foreground="?selectableItemBackground"
|
||||||
|
android:foregroundGravity="center"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:ignore="DuplicateIncludedIds"
|
||||||
|
tools:src="@drawable/featured_graphics"/>
|
||||||
|
|
||||||
<include layout="@layout/layout_card_media_preview_item"/>
|
<org.mariotaku.twidere.view.MediaPreviewImageView
|
||||||
</com.commonsware.cwac.layouts.AspectLockedFrameLayout>
|
android:id="@+id/mediaPreviewItem2"
|
||||||
|
|
||||||
<com.commonsware.cwac.layouts.AspectLockedFrameLayout
|
|
||||||
android:id="@+id/media_preview_item_2"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:foreground="?selectableItemBackground">
|
android:contentDescription="@string/media"
|
||||||
|
android:foreground="?selectableItemBackground"
|
||||||
|
android:foregroundGravity="center"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:ignore="DuplicateIncludedIds"
|
||||||
|
tools:src="@drawable/featured_graphics"/>
|
||||||
|
|
||||||
<include layout="@layout/layout_card_media_preview_item"/>
|
<org.mariotaku.twidere.view.MediaPreviewImageView
|
||||||
</com.commonsware.cwac.layouts.AspectLockedFrameLayout>
|
android:id="@+id/mediaPreviewItem3"
|
||||||
|
|
||||||
<com.commonsware.cwac.layouts.AspectLockedFrameLayout
|
|
||||||
android:id="@+id/media_preview_item_3"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:foreground="?selectableItemBackground">
|
android:contentDescription="@string/media"
|
||||||
|
android:foreground="?selectableItemBackground"
|
||||||
|
android:foregroundGravity="center"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:ignore="DuplicateIncludedIds"
|
||||||
|
tools:src="@drawable/featured_graphics"/>
|
||||||
|
|
||||||
<include layout="@layout/layout_card_media_preview_item"/>
|
|
||||||
|
|
||||||
</com.commonsware.cwac.layouts.AspectLockedFrameLayout>
|
|
||||||
</merge>
|
</merge>
|
|
@ -1,44 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
~ Twidere - Twitter client for Android
|
|
||||||
~
|
|
||||||
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
|
||||||
~
|
|
||||||
~ This program is free software: you can redistribute it and/or modify
|
|
||||||
~ it under the terms of the GNU General Public License as published by
|
|
||||||
~ the Free Software Foundation, either version 3 of the License, or
|
|
||||||
~ (at your option) any later version.
|
|
||||||
~
|
|
||||||
~ This program is distributed in the hope that it will be useful,
|
|
||||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
~ GNU General Public License for more details.
|
|
||||||
~
|
|
||||||
~ You should have received a copy of the GNU General Public License
|
|
||||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<merge 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">
|
|
||||||
|
|
||||||
<org.mariotaku.twidere.view.MediaPreviewImageView
|
|
||||||
android:id="@+id/mediaPreview"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:contentDescription="@string/media"
|
|
||||||
android:foregroundGravity="center"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
tools:ignore="DuplicateIncludedIds"
|
|
||||||
tools:src="@drawable/featured_graphics"/>
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/media_preview_progress"
|
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_margin="@dimen/element_spacing_large"
|
|
||||||
android:visibility="gone"/>
|
|
||||||
</merge>
|
|
Loading…
Reference in New Issue