980 lines
35 KiB
Kotlin
980 lines
35 KiB
Kotlin
package jp.juggler.subwaytooter.itemviewholder
|
|
|
|
import android.content.res.ColorStateList
|
|
import android.graphics.Typeface
|
|
import android.text.Spannable
|
|
import android.text.SpannableString
|
|
import android.text.TextUtils
|
|
import android.text.style.BackgroundColorSpan
|
|
import android.util.TypedValue
|
|
import android.view.Gravity
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import android.widget.*
|
|
import androidx.core.content.ContextCompat
|
|
import com.google.android.flexbox.JustifyContent
|
|
import jp.juggler.subwaytooter.*
|
|
import jp.juggler.subwaytooter.api.entity.TimelineItem
|
|
import jp.juggler.subwaytooter.api.entity.TootAccountRef
|
|
import jp.juggler.subwaytooter.api.entity.TootStatus
|
|
import jp.juggler.subwaytooter.column.Column
|
|
import jp.juggler.subwaytooter.columnviewholder.ItemListAdapter
|
|
import jp.juggler.subwaytooter.drawable.PreviewCardBorder
|
|
import jp.juggler.subwaytooter.table.SavedAccount
|
|
import jp.juggler.subwaytooter.util.*
|
|
import jp.juggler.subwaytooter.view.*
|
|
import jp.juggler.util.LogCategory
|
|
import jp.juggler.util.applyAlphaMultiplier
|
|
import jp.juggler.util.attrColor
|
|
import org.jetbrains.anko.*
|
|
|
|
class ItemViewHolder(
|
|
val activity: ActMain,
|
|
) : View.OnClickListener, View.OnLongClickListener {
|
|
|
|
companion object {
|
|
|
|
val log = LogCategory("ItemViewHolder")
|
|
var toot_color_unlisted: Int = 0
|
|
var toot_color_follower: Int = 0
|
|
var toot_color_direct_user: Int = 0
|
|
var toot_color_direct_me: Int = 0
|
|
}
|
|
|
|
val viewRoot: View
|
|
|
|
var bSimpleList: Boolean = false
|
|
|
|
lateinit var column: Column
|
|
|
|
internal lateinit var listAdapter: ItemListAdapter
|
|
|
|
lateinit var llBoosted: View
|
|
lateinit var ivBoosted: ImageView
|
|
lateinit var tvBoosted: TextView
|
|
lateinit var tvBoostedAcct: TextView
|
|
lateinit var tvBoostedTime: TextView
|
|
|
|
lateinit var llReply: View
|
|
lateinit var ivReply: ImageView
|
|
lateinit var tvReply: TextView
|
|
|
|
lateinit var llFollow: View
|
|
lateinit var ivFollow: MyNetworkImageView
|
|
lateinit var tvFollowerName: TextView
|
|
lateinit var tvFollowerAcct: TextView
|
|
lateinit var btnFollow: ImageButton
|
|
lateinit var ivFollowedBy: ImageView
|
|
|
|
lateinit var llStatus: View
|
|
lateinit var ivAvatar: MyNetworkImageView
|
|
lateinit var tvName: TextView
|
|
lateinit var tvTime: TextView
|
|
lateinit var tvAcct: TextView
|
|
|
|
lateinit var llContentWarning: View
|
|
lateinit var tvContentWarning: MyTextView
|
|
lateinit var btnContentWarning: Button
|
|
|
|
lateinit var llContents: View
|
|
lateinit var tvMentions: MyTextView
|
|
internal lateinit var tvContent: MyTextView
|
|
|
|
lateinit var flMedia: View
|
|
lateinit var llMedia: View
|
|
lateinit var btnShowMedia: BlurhashView
|
|
lateinit var ivMedia1: MyNetworkImageView
|
|
lateinit var ivMedia2: MyNetworkImageView
|
|
lateinit var ivMedia3: MyNetworkImageView
|
|
lateinit var ivMedia4: MyNetworkImageView
|
|
lateinit var btnHideMedia: ImageButton
|
|
|
|
lateinit var statusButtonsViewHolder: StatusButtonsViewHolder
|
|
lateinit var llButtonBar: View
|
|
|
|
lateinit var llSearchTag: View
|
|
lateinit var btnSearchTag: Button
|
|
lateinit var btnGapHead: ImageButton
|
|
lateinit var btnGapTail: ImageButton
|
|
lateinit var llTrendTag: View
|
|
lateinit var tvTrendTagName: TextView
|
|
lateinit var tvTrendTagDesc: TextView
|
|
lateinit var tvTrendTagCount: TextView
|
|
lateinit var cvTagHistory: TagHistoryView
|
|
|
|
lateinit var llList: View
|
|
lateinit var btnListTL: Button
|
|
lateinit var btnListMore: ImageButton
|
|
|
|
lateinit var llFollowRequest: View
|
|
lateinit var btnFollowRequestAccept: ImageButton
|
|
lateinit var btnFollowRequestDeny: ImageButton
|
|
|
|
lateinit var llFilter: View
|
|
lateinit var tvFilterPhrase: TextView
|
|
lateinit var tvFilterDetail: TextView
|
|
|
|
lateinit var tvMediaDescription: TextView
|
|
|
|
lateinit var llCardOuter: View
|
|
lateinit var tvCardText: MyTextView
|
|
lateinit var flCardImage: View
|
|
lateinit var llCardImage: View
|
|
lateinit var ivCardImage: MyNetworkImageView
|
|
lateinit var btnCardImageHide: ImageButton
|
|
lateinit var btnCardImageShow: BlurhashView
|
|
|
|
lateinit var llExtra: LinearLayout
|
|
|
|
lateinit var llConversationIcons: View
|
|
lateinit var ivConversationIcon1: MyNetworkImageView
|
|
lateinit var ivConversationIcon2: MyNetworkImageView
|
|
lateinit var ivConversationIcon3: MyNetworkImageView
|
|
lateinit var ivConversationIcon4: MyNetworkImageView
|
|
lateinit var tvConversationIconsMore: TextView
|
|
lateinit var tvConversationParticipants: TextView
|
|
|
|
lateinit var tvApplication: TextView
|
|
|
|
lateinit var tvMessageHolder: TextView
|
|
|
|
lateinit var llOpenSticker: View
|
|
lateinit var ivOpenSticker: MyNetworkImageView
|
|
lateinit var tvOpenSticker: TextView
|
|
|
|
lateinit var tvLastStatusAt: TextView
|
|
|
|
lateinit var accessInfo: SavedAccount
|
|
|
|
var buttonsForStatus: StatusButtons? = null
|
|
|
|
var item: TimelineItem? = null
|
|
|
|
var statusShowing: TootStatus? = null
|
|
var statusReply: TootStatus? = null
|
|
var statusAccount: TootAccountRef? = null
|
|
var boostAccount: TootAccountRef? = null
|
|
var followAccount: TootAccountRef? = null
|
|
|
|
var boostTime: Long = 0L
|
|
|
|
var contentColor: Int = 0
|
|
var acctColor: Int = 0
|
|
var contentColorCsl: ColorStateList = ColorStateList.valueOf(0)
|
|
|
|
val boostInvalidator: NetworkEmojiInvalidator
|
|
val replyInvalidator: NetworkEmojiInvalidator
|
|
val followInvalidator: NetworkEmojiInvalidator
|
|
val nameInvalidator: NetworkEmojiInvalidator
|
|
val contentInvalidator: NetworkEmojiInvalidator
|
|
val spoilerInvalidator: NetworkEmojiInvalidator
|
|
val lastActiveInvalidator: NetworkEmojiInvalidator
|
|
val extraInvalidatorList = ArrayList<NetworkEmojiInvalidator>()
|
|
|
|
var boostedAction: ItemViewHolder.() -> Unit = defaultBoostedAction
|
|
|
|
init {
|
|
this.viewRoot = inflate(activity)
|
|
|
|
for (v in arrayOf(
|
|
btnListTL,
|
|
btnListMore,
|
|
btnSearchTag,
|
|
btnGapHead,
|
|
btnGapTail,
|
|
btnContentWarning,
|
|
btnShowMedia,
|
|
ivMedia1,
|
|
ivMedia2,
|
|
ivMedia3,
|
|
ivMedia4,
|
|
btnFollow,
|
|
ivCardImage,
|
|
btnCardImageHide,
|
|
btnCardImageShow,
|
|
ivAvatar,
|
|
llBoosted,
|
|
llReply,
|
|
llFollow,
|
|
btnFollow,
|
|
btnFollowRequestAccept,
|
|
btnFollowRequestDeny,
|
|
btnHideMedia,
|
|
llTrendTag,
|
|
llFilter
|
|
)) {
|
|
v.setOnClickListener(this)
|
|
}
|
|
|
|
for (v in arrayOf(
|
|
btnSearchTag,
|
|
btnFollow,
|
|
ivCardImage,
|
|
llBoosted,
|
|
llReply,
|
|
llFollow,
|
|
llConversationIcons,
|
|
ivAvatar,
|
|
llTrendTag
|
|
)) {
|
|
v.setOnLongClickListener(this)
|
|
}
|
|
|
|
//
|
|
tvContent.movementMethod = MyLinkMovementMethod
|
|
tvMentions.movementMethod = MyLinkMovementMethod
|
|
tvContentWarning.movementMethod = MyLinkMovementMethod
|
|
tvMediaDescription.movementMethod = MyLinkMovementMethod
|
|
tvCardText.movementMethod = MyLinkMovementMethod
|
|
|
|
var f: Float
|
|
|
|
f = activity.timelineFontSizeSp
|
|
if (!f.isNaN()) {
|
|
tvFollowerName.textSize = f
|
|
tvName.textSize = f
|
|
tvMentions.textSize = f
|
|
tvContentWarning.textSize = f
|
|
tvContent.textSize = f
|
|
btnShowMedia.textSize = f
|
|
btnCardImageShow.textSize = f
|
|
tvApplication.textSize = f
|
|
tvMessageHolder.textSize = f
|
|
btnListTL.textSize = f
|
|
tvTrendTagName.textSize = f
|
|
tvTrendTagCount.textSize = f
|
|
tvFilterPhrase.textSize = f
|
|
tvMediaDescription.textSize = f
|
|
tvCardText.textSize = f
|
|
tvConversationIconsMore.textSize = f
|
|
tvConversationParticipants.textSize = f
|
|
}
|
|
|
|
f = activity.notificationTlFontSizeSp
|
|
if (!f.isNaN()) {
|
|
tvBoosted.textSize = f
|
|
tvReply.textSize = f
|
|
}
|
|
|
|
f = activity.acctFontSizeSp
|
|
if (!f.isNaN()) {
|
|
tvBoostedAcct.textSize = f
|
|
tvBoostedTime.textSize = f
|
|
tvFollowerAcct.textSize = f
|
|
tvLastStatusAt.textSize = f
|
|
tvAcct.textSize = f
|
|
tvTime.textSize = f
|
|
tvTrendTagDesc.textSize = f
|
|
tvFilterDetail.textSize = f
|
|
}
|
|
|
|
val spacing = activity.timelineSpacing
|
|
if (spacing != null) {
|
|
tvFollowerName.setLineSpacing(0f, spacing)
|
|
tvName.setLineSpacing(0f, spacing)
|
|
tvMentions.setLineSpacing(0f, spacing)
|
|
tvContentWarning.setLineSpacing(0f, spacing)
|
|
tvContent.setLineSpacing(0f, spacing)
|
|
btnShowMedia.setLineSpacing(0f, spacing)
|
|
btnCardImageShow.setLineSpacing(0f, spacing)
|
|
tvApplication.setLineSpacing(0f, spacing)
|
|
tvMessageHolder.setLineSpacing(0f, spacing)
|
|
btnListTL.setLineSpacing(0f, spacing)
|
|
tvTrendTagName.setLineSpacing(0f, spacing)
|
|
tvTrendTagCount.setLineSpacing(0f, spacing)
|
|
tvFilterPhrase.setLineSpacing(0f, spacing)
|
|
tvMediaDescription.setLineSpacing(0f, spacing)
|
|
tvCardText.setLineSpacing(0f, spacing)
|
|
tvConversationIconsMore.setLineSpacing(0f, spacing)
|
|
tvConversationParticipants.setLineSpacing(0f, spacing)
|
|
tvBoosted.setLineSpacing(0f, spacing)
|
|
tvReply.setLineSpacing(0f, spacing)
|
|
tvLastStatusAt.setLineSpacing(0f, spacing)
|
|
}
|
|
|
|
var s = activity.avatarIconSize
|
|
ivAvatar.layoutParams.height = s
|
|
ivAvatar.layoutParams.width = s
|
|
ivFollow.layoutParams.width = s
|
|
ivBoosted.layoutParams.width = s
|
|
|
|
s = ActMain.replyIconSize + (activity.density * 8).toInt()
|
|
ivReply.layoutParams.width = s
|
|
ivReply.layoutParams.height = s
|
|
|
|
s = activity.notificationTlIconSize
|
|
ivBoosted.layoutParams.height = s
|
|
|
|
this.contentInvalidator = NetworkEmojiInvalidator(activity.handler, tvContent)
|
|
this.spoilerInvalidator = NetworkEmojiInvalidator(activity.handler, tvContentWarning)
|
|
this.boostInvalidator = NetworkEmojiInvalidator(activity.handler, tvBoosted)
|
|
this.replyInvalidator = NetworkEmojiInvalidator(activity.handler, tvReply)
|
|
this.followInvalidator = NetworkEmojiInvalidator(activity.handler, tvFollowerName)
|
|
this.nameInvalidator = NetworkEmojiInvalidator(activity.handler, tvName)
|
|
this.lastActiveInvalidator = NetworkEmojiInvalidator(activity.handler, tvLastStatusAt)
|
|
|
|
val cardBackground = llCardOuter.background
|
|
if (cardBackground is PreviewCardBorder) {
|
|
val density = activity.density
|
|
cardBackground.round = (density * 8f)
|
|
cardBackground.width = (density * 1f)
|
|
}
|
|
|
|
val textShowMedia = SpannableString(activity.getString(R.string.tap_to_show))
|
|
.apply {
|
|
val colorBg = activity.attrColor(R.attr.colorShowMediaBackground)
|
|
.applyAlphaMultiplier(0.5f)
|
|
setSpan(
|
|
BackgroundColorSpan(colorBg),
|
|
0,
|
|
this.length,
|
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
|
)
|
|
}
|
|
|
|
btnShowMedia.text = textShowMedia
|
|
btnCardImageShow.text = textShowMedia
|
|
}
|
|
|
|
override fun onClick(v: View?) = onClickImpl(v)
|
|
override fun onLongClick(v: View?): Boolean = onLongClickImpl(v)
|
|
|
|
fun onViewRecycled() {
|
|
}
|
|
|
|
fun getAccount() = statusAccount ?: boostAccount ?: followAccount
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
private fun _LinearLayout.inflateBoosted() {
|
|
llBoosted = linearLayout {
|
|
lparams(matchParent, wrapContent) {
|
|
bottomMargin = dip(6)
|
|
}
|
|
backgroundResource = R.drawable.btn_bg_transparent_round6dp
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
|
|
ivBoosted = imageView {
|
|
scaleType = ImageView.ScaleType.FIT_END
|
|
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
|
}.lparams(dip(48), dip(32)) {
|
|
endMargin = dip(4)
|
|
}
|
|
|
|
verticalLayout {
|
|
lparams(dip(0), wrapContent) {
|
|
weight = 1f
|
|
}
|
|
|
|
linearLayout {
|
|
lparams(matchParent, wrapContent)
|
|
|
|
tvBoostedAcct = textView {
|
|
ellipsize = TextUtils.TruncateAt.END
|
|
gravity = Gravity.END
|
|
maxLines = 1
|
|
textSize = 12f // textSize の単位はSP
|
|
// tools:text ="who@hoge"
|
|
}.lparams(dip(0), wrapContent) {
|
|
weight = 1f
|
|
}
|
|
|
|
tvBoostedTime = textView {
|
|
|
|
startPadding = dip(2)
|
|
|
|
gravity = Gravity.END
|
|
textSize = 12f // textSize の単位はSP
|
|
// tools:ignore="RtlSymmetry"
|
|
// tools:text="2017-04-16 09:37:14"
|
|
}.lparams(wrapContent, wrapContent)
|
|
}
|
|
|
|
tvBoosted = textView {
|
|
// tools:text = "~にブーストされました"
|
|
}.lparams(matchParent, wrapContent)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateFollowed() {
|
|
llFollow = linearLayout {
|
|
lparams(matchParent, wrapContent)
|
|
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
|
|
ivFollow = myNetworkImageView {
|
|
contentDescription = context.getString(R.string.thumbnail)
|
|
scaleType = ImageView.ScaleType.FIT_END
|
|
}.lparams(dip(48), dip(40)) {
|
|
endMargin = dip(4)
|
|
}
|
|
|
|
verticalLayout {
|
|
|
|
lparams(dip(0), wrapContent) {
|
|
weight = 1f
|
|
}
|
|
|
|
tvFollowerName = textView {
|
|
// tools:text="Follower Name"
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
tvFollowerAcct = textView {
|
|
setPaddingStartEnd(dip(4), dip(4))
|
|
textSize = 12f // SP
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
tvLastStatusAt = myTextView {
|
|
setPaddingStartEnd(dip(4), dip(4))
|
|
textSize = 12f // SP
|
|
}.lparams(matchParent, wrapContent)
|
|
}
|
|
|
|
frameLayout {
|
|
lparams(dip(40), dip(40)) {
|
|
startMargin = dip(4)
|
|
}
|
|
|
|
btnFollow = imageButton {
|
|
background =
|
|
ContextCompat.getDrawable(
|
|
context,
|
|
R.drawable.btn_bg_transparent_round6dp
|
|
)
|
|
contentDescription = context.getString(R.string.follow)
|
|
scaleType = ImageView.ScaleType.CENTER
|
|
// tools:src="?attr/ic_follow_plus"
|
|
}.lparams(matchParent, matchParent)
|
|
|
|
ivFollowedBy = imageView {
|
|
scaleType = ImageView.ScaleType.CENTER
|
|
// tools:src="?attr/ic_followed_by"
|
|
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
|
}.lparams(matchParent, matchParent)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateVerticalMediaOne(thumbnailHeight: Int) =
|
|
myNetworkImageView {
|
|
background = ContextCompat.getDrawable(context, R.drawable.bg_thumbnail)
|
|
contentDescription = context.getString(R.string.thumbnail)
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
}.lparams(matchParent, thumbnailHeight) {
|
|
topMargin = dip(3)
|
|
}
|
|
|
|
private fun _LinearLayout.inflateVerticalMedia(thumbnailHeight: Int) =
|
|
frameLayout {
|
|
lparams(matchParent, wrapContent) {
|
|
topMargin = dip(3)
|
|
}
|
|
llMedia = verticalLayout {
|
|
lparams(matchParent, matchParent)
|
|
|
|
btnHideMedia = imageButton {
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
contentDescription = context.getString(R.string.hide)
|
|
imageResource = R.drawable.ic_close
|
|
}.lparams(dip(32), dip(32)) {
|
|
gravity = Gravity.END
|
|
}
|
|
ivMedia1 = inflateVerticalMediaOne(thumbnailHeight)
|
|
ivMedia2 = inflateVerticalMediaOne(thumbnailHeight)
|
|
ivMedia3 = inflateVerticalMediaOne(thumbnailHeight)
|
|
ivMedia4 = inflateVerticalMediaOne(thumbnailHeight)
|
|
}
|
|
|
|
btnShowMedia = blurhashView {
|
|
errorColor = context.attrColor(R.attr.colorShowMediaBackground)
|
|
gravity = Gravity.CENTER
|
|
textColor = context.attrColor(R.attr.colorShowMediaText)
|
|
minHeightCompat = dip(48)
|
|
}.lparams(matchParent, thumbnailHeight)
|
|
}
|
|
|
|
private fun _LinearLayout.inflateHorizontalMediaOne(trail: Boolean) =
|
|
myNetworkImageView {
|
|
background = ContextCompat.getDrawable(context, R.drawable.bg_thumbnail)
|
|
contentDescription = context.getString(R.string.thumbnail)
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
}.lparams(0, matchParent) {
|
|
weight = 1f
|
|
if (trail) startMargin = dip(8)
|
|
}
|
|
|
|
private fun _LinearLayout.inflateHorizontalMedia(thumbnailHeight: Int): View {
|
|
return frameLayout {
|
|
lparams(matchParent, thumbnailHeight) { topMargin = dip(3) }
|
|
llMedia = linearLayout {
|
|
lparams(matchParent, matchParent)
|
|
ivMedia1 = inflateHorizontalMediaOne(trail = false)
|
|
ivMedia2 = inflateHorizontalMediaOne(trail = true)
|
|
ivMedia3 = inflateHorizontalMediaOne(trail = true)
|
|
ivMedia4 = inflateHorizontalMediaOne(trail = true)
|
|
btnHideMedia = imageButton {
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
contentDescription = context.getString(R.string.hide)
|
|
imageResource = R.drawable.ic_close
|
|
}.lparams(dip(32), matchParent) {
|
|
startMargin = dip(8)
|
|
}
|
|
}
|
|
|
|
btnShowMedia = blurhashView {
|
|
errorColor = context.attrColor(R.attr.colorShowMediaBackground)
|
|
textColor = context.attrColor(R.attr.colorShowMediaText)
|
|
gravity = Gravity.CENTER
|
|
}.lparams(matchParent, matchParent)
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateCard(actMain: ActMain) {
|
|
llCardOuter = verticalLayout {
|
|
lparams(matchParent, wrapContent) {
|
|
topMargin = dip(3)
|
|
startMargin = dip(12)
|
|
endMargin = dip(6)
|
|
}
|
|
padding = dip(3)
|
|
bottomPadding = dip(6)
|
|
|
|
background = PreviewCardBorder()
|
|
|
|
tvCardText = myTextView {
|
|
}.lparams(matchParent, wrapContent) {
|
|
}
|
|
|
|
flCardImage = frameLayout {
|
|
lparams(matchParent, actMain.appState.mediaThumbHeight) {
|
|
topMargin = dip(3)
|
|
}
|
|
|
|
llCardImage = linearLayout {
|
|
lparams(matchParent, matchParent)
|
|
|
|
ivCardImage = myNetworkImageView {
|
|
contentDescription = context.getString(R.string.thumbnail)
|
|
scaleType = when {
|
|
PrefB.bpDontCropMediaThumb(App1.pref) -> ImageView.ScaleType.FIT_CENTER
|
|
else -> ImageView.ScaleType.CENTER_CROP
|
|
}
|
|
}.lparams(0, matchParent) {
|
|
weight = 1f
|
|
}
|
|
btnCardImageHide = imageButton {
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
contentDescription = context.getString(R.string.hide)
|
|
imageResource = R.drawable.ic_close
|
|
}.lparams(dip(32), matchParent) {
|
|
startMargin = dip(4)
|
|
}
|
|
}
|
|
|
|
btnCardImageShow = blurhashView {
|
|
errorColor = context.attrColor(R.attr.colorShowMediaBackground)
|
|
textColor = context.attrColor(R.attr.colorShowMediaText)
|
|
gravity = Gravity.CENTER
|
|
}.lparams(matchParent, matchParent)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateStatusReplyInfo() {
|
|
llReply = linearLayout {
|
|
lparams(matchParent, wrapContent) {
|
|
bottomMargin = dip(3)
|
|
}
|
|
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
|
|
ivReply = imageView {
|
|
scaleType = ImageView.ScaleType.FIT_END
|
|
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
|
padding = dip(4)
|
|
}.lparams(dip(32), dip(32)) {
|
|
endMargin = dip(4)
|
|
}
|
|
|
|
tvReply = textView {
|
|
}.lparams(dip(0), wrapContent) {
|
|
weight = 1f
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateStatusContentWarning() {
|
|
llContentWarning = linearLayout {
|
|
lparams(matchParent, wrapContent) {
|
|
topMargin = dip(3)
|
|
isBaselineAligned = false
|
|
}
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
|
|
btnContentWarning = button {
|
|
backgroundDrawable =
|
|
ContextCompat.getDrawable(context, R.drawable.bg_button_cw)
|
|
minWidthCompat = dip(40)
|
|
padding = dip(4)
|
|
//tools:text="見る"
|
|
}.lparams(wrapContent, dip(40)) {
|
|
endMargin = dip(8)
|
|
}
|
|
|
|
verticalLayout {
|
|
lparams(dip(0), wrapContent) {
|
|
weight = 1f
|
|
}
|
|
|
|
tvMentions = myTextView {}.lparams(matchParent, wrapContent)
|
|
|
|
tvContentWarning = myTextView {
|
|
}.lparams(matchParent, wrapContent) {
|
|
topMargin = dip(3)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateStatusContents(actMain: ActMain) {
|
|
llContents = verticalLayout {
|
|
lparams(matchParent, wrapContent)
|
|
|
|
tvContent = myTextView {
|
|
setLineSpacing(lineSpacingExtra, 1.1f)
|
|
// tools:text="Contents\nContents"
|
|
}.lparams(matchParent, wrapContent) {
|
|
topMargin = dip(3)
|
|
}
|
|
|
|
val thumbnailHeight = actMain.appState.mediaThumbHeight
|
|
flMedia = when (PrefB.bpVerticalArrangeThumbnails(actMain.pref)) {
|
|
true -> inflateVerticalMedia(thumbnailHeight)
|
|
else -> inflateHorizontalMedia(thumbnailHeight)
|
|
}
|
|
|
|
tvMediaDescription = textView {}.lparams(matchParent, wrapContent)
|
|
|
|
inflateCard(actMain)
|
|
|
|
llExtra = verticalLayout {
|
|
lparams(matchParent, wrapContent) {
|
|
topMargin = dip(0)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateStatusButtons(actMain: ActMain) {
|
|
// button bar
|
|
statusButtonsViewHolder = StatusButtonsViewHolder(
|
|
actMain,
|
|
matchParent,
|
|
3f,
|
|
justifyContent = when (PrefI.ipBoostButtonJustify(App1.pref)) {
|
|
0 -> JustifyContent.FLEX_START
|
|
1 -> JustifyContent.CENTER
|
|
else -> JustifyContent.FLEX_END
|
|
}
|
|
)
|
|
llButtonBar = statusButtonsViewHolder.viewRoot
|
|
addView(llButtonBar)
|
|
}
|
|
|
|
private fun _LinearLayout.inflateOpenSticker() {
|
|
|
|
llOpenSticker = linearLayout {
|
|
lparams(matchParent, wrapContent)
|
|
|
|
ivOpenSticker = myNetworkImageView {
|
|
}.lparams(dip(16), dip(16)) {
|
|
isBaselineAligned = false
|
|
}
|
|
|
|
tvOpenSticker = textView {
|
|
setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10f)
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
setPaddingStartEnd(dip(4f), dip(4f))
|
|
}.lparams(0, dip(16)) {
|
|
isBaselineAligned = false
|
|
weight = 1f
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateStatusAcctTime() {
|
|
linearLayout {
|
|
lparams(matchParent, wrapContent)
|
|
tvAcct = textView {
|
|
ellipsize = TextUtils.TruncateAt.END
|
|
gravity = Gravity.END
|
|
maxLines = 1
|
|
textSize = 12f // SP
|
|
// tools:text="who@hoge"
|
|
}.lparams(dip(0), wrapContent) {
|
|
weight = 1f
|
|
}
|
|
|
|
tvTime = textView {
|
|
gravity = Gravity.END
|
|
startPadding = dip(2)
|
|
textSize = 12f // SP
|
|
// tools:ignore="RtlSymmetry"
|
|
// tools:text="2017-04-16 09:37:14"
|
|
}.lparams(wrapContent, wrapContent)
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateStatusAvatar() {
|
|
ivAvatar = myNetworkImageView {
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
contentDescription = context.getString(R.string.thumbnail)
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
}.lparams(dip(48), dip(48)) {
|
|
topMargin = dip(4)
|
|
endMargin = dip(4)
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateStatus(actMain: ActMain) {
|
|
llStatus = verticalLayout {
|
|
lparams(matchParent, wrapContent)
|
|
|
|
inflateStatusAcctTime()
|
|
|
|
// horizontal split : avatar and other
|
|
linearLayout {
|
|
lparams(matchParent, wrapContent)
|
|
inflateStatusAvatar()
|
|
verticalLayout {
|
|
lparams(0, wrapContent) { weight = 1f }
|
|
|
|
tvName = textView {
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
inflateOpenSticker()
|
|
inflateStatusReplyInfo()
|
|
inflateStatusContentWarning()
|
|
inflateStatusContents(actMain)
|
|
inflateStatusButtons(actMain)
|
|
|
|
tvApplication = textView {
|
|
gravity = Gravity.END
|
|
}.lparams(matchParent, wrapContent)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateConversationIconOne() =
|
|
myNetworkImageView {
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
}.lparams(dip(24), dip(24)) {
|
|
endMargin = dip(3)
|
|
}
|
|
|
|
private fun _LinearLayout.inflateConversationIcons() {
|
|
llConversationIcons = linearLayout {
|
|
lparams(matchParent, dip(40))
|
|
|
|
isBaselineAligned = false
|
|
gravity = Gravity.START or Gravity.CENTER_VERTICAL
|
|
|
|
tvConversationParticipants = textView {
|
|
text = context.getString(R.string.participants)
|
|
}.lparams(wrapContent, wrapContent) {
|
|
endMargin = dip(3)
|
|
}
|
|
|
|
ivConversationIcon1 = inflateConversationIconOne()
|
|
ivConversationIcon2 = inflateConversationIconOne()
|
|
ivConversationIcon3 = inflateConversationIconOne()
|
|
ivConversationIcon4 = inflateConversationIconOne()
|
|
|
|
tvConversationIconsMore = textView {}.lparams(wrapContent, wrapContent)
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateSearchTag() {
|
|
llSearchTag = linearLayout {
|
|
lparams(matchParent, wrapContent)
|
|
|
|
btnSearchTag = button {
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
allCaps = false
|
|
}.lparams(0, wrapContent) {
|
|
weight = 1f
|
|
}
|
|
|
|
btnGapHead = imageButton {
|
|
background = ContextCompat.getDrawable(
|
|
context,
|
|
R.drawable.btn_bg_transparent_round6dp
|
|
)
|
|
contentDescription = context.getString(R.string.read_gap_head)
|
|
imageResource = R.drawable.ic_arrow_drop_down
|
|
}.lparams(dip(32), matchParent) {
|
|
startMargin = dip(8)
|
|
}
|
|
|
|
btnGapTail = imageButton {
|
|
background = ContextCompat.getDrawable(
|
|
context,
|
|
R.drawable.btn_bg_transparent_round6dp
|
|
)
|
|
contentDescription = context.getString(R.string.read_gap_tail)
|
|
imageResource = R.drawable.ic_arrow_drop_up
|
|
}.lparams(dip(32), matchParent) {
|
|
startMargin = dip(8)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateTrendTag() {
|
|
llTrendTag = linearLayout {
|
|
lparams(matchParent, wrapContent)
|
|
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
|
|
verticalLayout {
|
|
lparams(0, wrapContent) {
|
|
weight = 1f
|
|
}
|
|
|
|
tvTrendTagName = textView {}.lparams(matchParent, wrapContent)
|
|
|
|
tvTrendTagDesc = textView {
|
|
textSize = 12f // SP
|
|
}.lparams(matchParent, wrapContent)
|
|
}
|
|
tvTrendTagCount = textView {}.lparams(wrapContent, wrapContent) {
|
|
startMargin = dip(6)
|
|
endMargin = dip(6)
|
|
}
|
|
|
|
cvTagHistory = trendTagHistoryView {}.lparams(dip(64), dip(32))
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateList() {
|
|
llList = linearLayout {
|
|
lparams(matchParent, wrapContent)
|
|
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
isBaselineAligned = false
|
|
minimumHeight = dip(40)
|
|
|
|
btnListTL = button {
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
allCaps = false
|
|
}.lparams(0, wrapContent) {
|
|
weight = 1f
|
|
}
|
|
|
|
btnListMore = imageButton {
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
imageResource = R.drawable.ic_more
|
|
contentDescription = context.getString(R.string.more)
|
|
}.lparams(dip(40), matchParent) {
|
|
startMargin = dip(4)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateMessageHolder() {
|
|
tvMessageHolder = textView {
|
|
padding = dip(4)
|
|
}.lparams(matchParent, wrapContent)
|
|
}
|
|
|
|
private fun _LinearLayout.inflateFollowRequest() {
|
|
llFollowRequest = linearLayout {
|
|
lparams(matchParent, wrapContent) {
|
|
topMargin = dip(6)
|
|
}
|
|
gravity = Gravity.END
|
|
|
|
btnFollowRequestAccept = imageButton {
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
contentDescription = context.getString(R.string.follow_accept)
|
|
imageResource = R.drawable.ic_check
|
|
setPadding(0, 0, 0, 0)
|
|
}.lparams(dip(48f), dip(32f))
|
|
|
|
btnFollowRequestDeny = imageButton {
|
|
background =
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
contentDescription = context.getString(R.string.follow_deny)
|
|
imageResource = R.drawable.ic_close
|
|
setPadding(0, 0, 0, 0)
|
|
}.lparams(dip(48f), dip(32f)) {
|
|
startMargin = dip(4)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun _LinearLayout.inflateFilter() {
|
|
llFilter = verticalLayout {
|
|
lparams(matchParent, wrapContent) {
|
|
}
|
|
minimumHeight = dip(40)
|
|
|
|
tvFilterPhrase = textView {
|
|
typeface = Typeface.DEFAULT_BOLD
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
tvFilterDetail = textView {
|
|
textSize = 12f // SP
|
|
}.lparams(matchParent, wrapContent)
|
|
}
|
|
}
|
|
|
|
fun inflate(actMain: ActMain) = with(actMain.UI {}) {
|
|
val b = Benchmark(log, "Item-Inflate", 40L)
|
|
val rv = verticalLayout {
|
|
// トップレベルのViewGroupのlparamsはイニシャライザ内部に置くしかないみたい
|
|
layoutParams =
|
|
androidx.recyclerview.widget.RecyclerView.LayoutParams(matchParent, wrapContent)
|
|
.apply {
|
|
marginStart = dip(8)
|
|
marginEnd = dip(8)
|
|
topMargin = dip(2f)
|
|
bottomMargin = dip(1f)
|
|
}
|
|
|
|
setPaddingRelative(dip(4), dip(1f), dip(4), dip(2f))
|
|
|
|
descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS
|
|
|
|
inflateBoosted()
|
|
inflateFollowed()
|
|
inflateStatus(actMain)
|
|
inflateConversationIcons()
|
|
inflateSearchTag()
|
|
inflateTrendTag()
|
|
inflateList()
|
|
inflateMessageHolder()
|
|
|
|
inflateFollowRequest()
|
|
inflateFilter()
|
|
}
|
|
b.report()
|
|
rv
|
|
}
|
|
}
|