adding media gallery timeline
This commit is contained in:
parent
c5713f5be0
commit
315dcd9002
|
@ -2,11 +2,11 @@
|
|||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
maven { url 'https://plugins.gradle.org/m2/' }
|
||||
maven { url 'https://maven.google.com' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.0-rc1'
|
||||
classpath 'com.android.tools.build:gradle:3.0.0-rc2'
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ allprojects {
|
|||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven { url 'https://maven.google.com' }
|
||||
google()
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,7 @@ subprojects {
|
|||
StethoBeanShellREPL : '0.3',
|
||||
ArchLifecycleExtensions: '1.0.0-beta2',
|
||||
ArchPaging : '1.0.0-alpha3',
|
||||
ConstraintLayout : '1.0.2',
|
||||
]
|
||||
|
||||
}
|
||||
|
|
|
@ -209,6 +209,7 @@ dependencies {
|
|||
implementation "com.android.support:customtabs:${libVersions['SupportLib']}"
|
||||
implementation "com.android.support:design:${libVersions['SupportLib']}"
|
||||
implementation "com.android.support:exifinterface:${libVersions['SupportLib']}"
|
||||
implementation "com.android.support.constraint:constraint-layout:${libVersions['ConstraintLayout']}"
|
||||
implementation "com.twitter:twitter-text:${libVersions['TwitterText']}"
|
||||
implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0'
|
||||
implementation 'com.squareup:otto:1.3.8'
|
||||
|
|
|
@ -36,7 +36,7 @@ class AccountSelectorAdapter(
|
|||
private val inflater: LayoutInflater,
|
||||
preferences: SharedPreferences,
|
||||
val requestManager: RequestManager
|
||||
) : RecyclerPagerAdapter() {
|
||||
) : RecyclerPagerAdapter<RecyclerPagerAdapter.ViewHolder>() {
|
||||
|
||||
internal var profileImageStyle: Int = preferences[profileImageStyleKey]
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ import java.util.*
|
|||
class ParcelableStatusesAdapter(
|
||||
context: Context,
|
||||
requestManager: RequestManager,
|
||||
@TimelineStyle val timelineStyle: Int
|
||||
@TimelineStyle private val timelineStyle: Int
|
||||
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, requestManager),
|
||||
IStatusesAdapter, IItemCountsAdapter {
|
||||
|
||||
|
@ -457,19 +457,26 @@ class ParcelableStatusesAdapter(
|
|||
parent: ViewGroup, @TimelineStyle timelineStyle: Int): IStatusViewHolder {
|
||||
when (timelineStyle) {
|
||||
TimelineStyle.STAGGERED -> {
|
||||
val view = inflater.inflate(R.layout.adapter_item_media_status, parent, false)
|
||||
val view = inflater.inflate(MediaStatusViewHolder.layoutResource, parent, false)
|
||||
val holder = MediaStatusViewHolder(adapter, view)
|
||||
holder.setOnClickListeners()
|
||||
holder.setupViewOptions()
|
||||
return holder
|
||||
}
|
||||
TimelineStyle.PLAIN, TimelineStyle.GALLERY -> {
|
||||
TimelineStyle.PLAIN -> {
|
||||
val view = inflater.inflate(StatusViewHolder.layoutResource, parent, false)
|
||||
val holder = StatusViewHolder(adapter, view)
|
||||
holder.setOnClickListeners()
|
||||
holder.setupViewOptions()
|
||||
return holder
|
||||
}
|
||||
TimelineStyle.GALLERY -> {
|
||||
val view = inflater.inflate(LargeMediaStatusViewHolder.layoutResource, parent, false)
|
||||
val holder = LargeMediaStatusViewHolder(adapter, view)
|
||||
holder.setOnClickListeners()
|
||||
holder.setupViewOptions()
|
||||
return holder
|
||||
}
|
||||
else -> throw AssertionError()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,8 @@ import android.util.SparseArray
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2016/12/9.
|
||||
*/
|
||||
abstract class RecyclerPagerAdapter : PagerAdapter() {
|
||||
private val viewHolders: SparseArray<ViewHolder> = SparseArray()
|
||||
abstract class RecyclerPagerAdapter<VH : RecyclerPagerAdapter.ViewHolder> : PagerAdapter() {
|
||||
private val viewHolders: SparseArray<VH> = SparseArray()
|
||||
|
||||
final override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||
val itemViewType = getItemViewType(position)
|
||||
|
@ -44,9 +41,9 @@ abstract class RecyclerPagerAdapter : PagerAdapter() {
|
|||
return (obj as ViewHolder).itemView == view
|
||||
}
|
||||
|
||||
abstract fun onCreateViewHolder(container: ViewGroup, position: Int, itemViewType: Int): ViewHolder
|
||||
abstract fun onCreateViewHolder(container: ViewGroup, position: Int, itemViewType: Int): VH
|
||||
|
||||
abstract fun onBindViewHolder(holder: ViewHolder, position: Int, itemViewType: Int)
|
||||
abstract fun onBindViewHolder(holder: VH, position: Int, itemViewType: Int)
|
||||
|
||||
open fun getItemViewType(position: Int): Int = 0
|
||||
|
||||
|
|
|
@ -21,16 +21,14 @@ package org.mariotaku.twidere.data.source
|
|||
|
||||
import android.arch.paging.TiledDataSource
|
||||
import android.content.ContentResolver
|
||||
import android.database.ContentObserver
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import org.mariotaku.ktextension.weak
|
||||
import org.mariotaku.twidere.extension.queryAll
|
||||
import org.mariotaku.twidere.extension.queryCount
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/10/13.
|
||||
*/
|
||||
|
||||
class CursorObjectTiledDataSource<T>(
|
||||
private val resolver: ContentResolver,
|
||||
val uri: Uri,
|
||||
|
@ -41,6 +39,19 @@ class CursorObjectTiledDataSource<T>(
|
|||
val cls: Class<T>
|
||||
) : TiledDataSource<T>() {
|
||||
|
||||
init {
|
||||
val weakThis = weak()
|
||||
val observer = object : ContentObserver(MainHandler) {
|
||||
override fun onChange(selfChange: Boolean) {
|
||||
weakThis.get()?.invalidate()
|
||||
}
|
||||
}
|
||||
addInvalidatedCallback cb@ {
|
||||
resolver.unregisterContentObserver(observer)
|
||||
}
|
||||
resolver.registerContentObserver(uri, false, observer)
|
||||
}
|
||||
|
||||
override fun countItems() = resolver.queryCount(uri, selection, selectionArgs)
|
||||
|
||||
override fun loadRange(startPosition: Int, count: Int): List<T> {
|
||||
|
|
|
@ -126,9 +126,7 @@ class AddStatusFilterDialogFragment : BaseDialogFragment() {
|
|||
|
||||
private val filterItemsInfo: Array<FilterItemInfo>
|
||||
get() {
|
||||
val args = arguments
|
||||
if (args == null || !args.containsKey(EXTRA_STATUS)) return emptyArray()
|
||||
val status = args.getParcelable<ParcelableStatus>(EXTRA_STATUS) ?: return emptyArray()
|
||||
val status = arguments.getParcelable<ParcelableStatus>(EXTRA_STATUS) ?: return emptyArray()
|
||||
val list = ArrayList<FilterItemInfo>()
|
||||
if (status.is_retweet && status.retweeted_by_user_key != null) {
|
||||
list.add(FilterItemInfo(FilterItemInfo.FILTER_TYPE_USER,
|
||||
|
@ -143,12 +141,8 @@ class AddStatusFilterDialogFragment : BaseDialogFragment() {
|
|||
list.add(FilterItemInfo(FilterItemInfo.FILTER_TYPE_USER, UserItem(status.user_key,
|
||||
status.user_name, status.user_screen_name)))
|
||||
val mentions = status.mentions
|
||||
if (mentions != null) {
|
||||
for (mention in mentions) {
|
||||
if (mention.key != status.user_key) {
|
||||
list.add(FilterItemInfo(FilterItemInfo.FILTER_TYPE_USER, mention))
|
||||
}
|
||||
}
|
||||
mentions?.filter { it.key != status.user_key }?.mapTo(list) {
|
||||
FilterItemInfo(FilterItemInfo.FILTER_TYPE_USER, it)
|
||||
}
|
||||
val hashtags = HashSet<String>()
|
||||
hashtags.addAll(extractor.extractHashtags(status.text_plain))
|
||||
|
|
|
@ -56,12 +56,9 @@ import org.mariotaku.twidere.adapter.iface.IContentAdapter
|
|||
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
|
||||
import org.mariotaku.twidere.annotation.FilterScope
|
||||
import org.mariotaku.twidere.annotation.TimelineStyle
|
||||
import org.mariotaku.twidere.constant.*
|
||||
import org.mariotaku.twidere.constant.IntentConstants.*
|
||||
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.*
|
||||
import org.mariotaku.twidere.constant.displaySensitiveContentsKey
|
||||
import org.mariotaku.twidere.constant.favoriteConfirmationKey
|
||||
import org.mariotaku.twidere.constant.loadItemLimitKey
|
||||
import org.mariotaku.twidere.constant.newDocumentApiKey
|
||||
import org.mariotaku.twidere.data.fetcher.StatusesFetcher
|
||||
import org.mariotaku.twidere.data.source.CursorObjectLivePagedListProvider
|
||||
import org.mariotaku.twidere.data.status.StatusesLivePagedListProvider
|
||||
|
@ -138,6 +135,7 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
|||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
registerForContextMenu(recyclerView)
|
||||
adapter.statusClickListener = StatusClickHandler()
|
||||
statuses = createLiveData()
|
||||
statuses.observe(this, Observer { onDataLoaded(it) })
|
||||
|
@ -166,12 +164,9 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
|||
override fun onCreateItemDecoration(context: Context, recyclerView: RecyclerView,
|
||||
layoutManager: LayoutManager): RecyclerView.ItemDecoration? {
|
||||
return when (timelineStyle) {
|
||||
TimelineStyle.PLAIN -> {
|
||||
createStatusesListItemDecoration(context, recyclerView, adapter)
|
||||
}
|
||||
else -> {
|
||||
super.onCreateItemDecoration(context, recyclerView, layoutManager)
|
||||
}
|
||||
TimelineStyle.PLAIN -> createStatusesListItemDecoration(context, recyclerView, adapter)
|
||||
TimelineStyle.GALLERY -> createStatusesListGalleryDecoration(context, recyclerView)
|
||||
else -> super.onCreateItemDecoration(context, recyclerView, layoutManager)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,12 +282,10 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
|||
|
||||
|
||||
protected open fun onDataLoaded(data: PagedList<ParcelableStatus>?) {
|
||||
val firstVisiblePosition = layoutManager.firstVisibleItemPosition
|
||||
adapter.statuses = data
|
||||
adapter.timelineFilter = timelineFilter
|
||||
when {
|
||||
// data is ExceptionResponseList -> {
|
||||
// showEmpty(R.drawable.ic_info_error_generic, data.exception.toString())
|
||||
// }
|
||||
data == null || data.isEmpty() -> {
|
||||
showEmpty(R.drawable.ic_info_refresh, getString(R.string.swipe_down_to_refresh))
|
||||
}
|
||||
|
@ -300,6 +293,11 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
|||
showContent()
|
||||
}
|
||||
}
|
||||
if (firstVisiblePosition == 0 && !preferences[readFromBottomKey]) {
|
||||
recyclerView.post {
|
||||
recyclerView.smoothScrollToPosition(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun getStatuses(param: ContentRefreshParam): Boolean
|
||||
|
@ -366,9 +364,10 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
|||
extraSelection.second?.addAllTo(expressionArgs)
|
||||
}
|
||||
val provider = CursorObjectLivePagedListProvider(context.contentResolver, contentUri,
|
||||
statusColumnsLite, Expression.and(*expressions.toTypedArray()).sql,
|
||||
Statuses.COLUMNS, Expression.and(*expressions.toTypedArray()).sql,
|
||||
expressionArgs.toTypedArray(), Statuses.DEFAULT_SORT_ORDER, ParcelableStatus::class.java)
|
||||
return provider.create(null, 20)
|
||||
return provider.create(null, PagedList.Config.Builder()
|
||||
.setPageSize(50).setEnablePlaceholders(false).build())
|
||||
}
|
||||
|
||||
private fun getFullStatus(position: Int): ParcelableStatus? {
|
||||
|
@ -441,6 +440,12 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
|||
IntentUtils.openStatus(activity, status, null)
|
||||
}
|
||||
|
||||
override fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean {
|
||||
val status = adapter.getStatus(position)
|
||||
System.identityHashCode(status)
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onItemActionClick(holder: RecyclerView.ViewHolder, id: Int, position: Int) {
|
||||
val status = getFullStatus(position) ?: return
|
||||
handleActionClick(this@AbsTimelineFragment, id, status,
|
||||
|
@ -476,10 +481,6 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
|||
IntentUtils.openStatus(activity, status.account_key, quotedId)
|
||||
}
|
||||
|
||||
override fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean {
|
||||
return super.onStatusLongClick(holder, position)
|
||||
}
|
||||
|
||||
override fun onUserProfileClick(holder: IStatusViewHolder, position: Int) {
|
||||
val status = adapter.getStatus(position)
|
||||
val intent = IntentUtils.userProfile(status.account_key, status.user_key,
|
||||
|
@ -683,6 +684,12 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
|||
return itemDecoration
|
||||
}
|
||||
|
||||
fun createStatusesListGalleryDecoration(context: Context, recyclerView: RecyclerView): RecyclerView.ItemDecoration {
|
||||
val itemDecoration = ExtendedDividerItemDecoration(context, (recyclerView.layoutManager as LinearLayoutManager).orientation)
|
||||
itemDecoration.setDecorationEndOffset(1)
|
||||
return itemDecoration
|
||||
}
|
||||
|
||||
fun selectAccountIntent(context: Context, status: ParcelableStatus, itemId: Long,
|
||||
sameHostOnly: Boolean = true): Intent {
|
||||
val intent = Intent(context, AccountSelectorActivity::class.java)
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.os.Bundle
|
|||
import org.mariotaku.abstask.library.TaskStarter
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.annotation.FilterScope
|
||||
import org.mariotaku.twidere.annotation.TimelineStyle
|
||||
import org.mariotaku.twidere.constant.IntentConstants
|
||||
import org.mariotaku.twidere.data.fetcher.StatusesFetcher
|
||||
import org.mariotaku.twidere.data.fetcher.UserMediaTimelineFetcher
|
||||
|
@ -39,6 +40,8 @@ class UserMediaTimelineFragment : AbsTimelineFragment() {
|
|||
|
||||
override val contentUri: Uri = Statuses.UserTimeline.CONTENT_URI
|
||||
|
||||
override val timelineStyle: Int = TimelineStyle.GALLERY
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
linkHandlerTitle = getString(R.string.title_media_timeline)
|
||||
|
|
|
@ -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.view.holder
|
||||
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import com.bumptech.glide.RequestManager
|
||||
import kotlinx.android.synthetic.main.adapter_item_large_media_status.view.*
|
||||
import kotlinx.android.synthetic.main.adapter_item_large_media_status_preview_item.view.*
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.adapter.RecyclerPagerAdapter
|
||||
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.view.ProfileImageView
|
||||
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
||||
|
||||
class LargeMediaStatusViewHolder(private val adapter: IStatusesAdapter, itemView: View) :
|
||||
RecyclerView.ViewHolder(itemView), IStatusViewHolder, View.OnClickListener, View.OnLongClickListener {
|
||||
override val profileImageView: ProfileImageView = itemView.profileImage
|
||||
override val profileTypeView: ImageView? = null
|
||||
|
||||
private val mediaPreviewAdapter: ImagePagerAdapter
|
||||
private val mediaPreviewPager = itemView.mediaPreviewPager
|
||||
private val nameView = itemView.nameView
|
||||
|
||||
private var listener: IStatusViewHolder.StatusClickListener? = null
|
||||
|
||||
|
||||
init {
|
||||
mediaPreviewAdapter = ImagePagerAdapter(adapter.requestManager)
|
||||
mediaPreviewPager.adapter = mediaPreviewAdapter
|
||||
}
|
||||
|
||||
override fun display(status: ParcelableStatus, displayInReplyTo: Boolean,
|
||||
displayPinned: Boolean) {
|
||||
val context = itemView.context
|
||||
adapter.requestManager.loadProfileImage(context, status,
|
||||
adapter.profileImageStyle, profileImageView.cornerRadius,
|
||||
profileImageView.cornerRadiusRatio).into(profileImageView)
|
||||
|
||||
nameView.name = status.user_name
|
||||
nameView.screenName = "@${status.user_screen_name}"
|
||||
nameView.updateText(adapter.bidiFormatter)
|
||||
|
||||
mediaPreviewAdapter.media = status.media
|
||||
}
|
||||
|
||||
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, current: ParcelableMedia, accountKey: UserKey?, id: Long) {
|
||||
}
|
||||
|
||||
override fun setStatusClickListener(listener: IStatusViewHolder.StatusClickListener?) {
|
||||
this.listener = listener
|
||||
itemView.itemContent.setOnClickListener(this)
|
||||
}
|
||||
|
||||
override fun setTextSize(textSize: Float) {
|
||||
|
||||
}
|
||||
|
||||
override fun playLikeAnimation(listener: LikeAnimationDrawable.OnLikedListener) {
|
||||
|
||||
}
|
||||
|
||||
fun setOnClickListeners() {
|
||||
setStatusClickListener(adapter.statusClickListener)
|
||||
}
|
||||
|
||||
fun setupViewOptions() {
|
||||
setTextSize(adapter.textSize)
|
||||
nameView.nameFirst = adapter.nameFirst
|
||||
}
|
||||
|
||||
private class ImagePagerAdapter(val requestManager: RequestManager) : RecyclerPagerAdapter<LargeMediaItemHolder>() {
|
||||
var media: Array<ParcelableMedia>? = null
|
||||
set(value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getCount() = media?.size ?: 0
|
||||
|
||||
override fun onCreateViewHolder(container: ViewGroup, position: Int, itemViewType: Int): LargeMediaItemHolder {
|
||||
return LargeMediaItemHolder(this, LayoutInflater.from(container.context)
|
||||
.inflate(LargeMediaItemHolder.layoutResource, container, false))
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: LargeMediaItemHolder, position: Int, itemViewType: Int) {
|
||||
holder.display(media!![position])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class LargeMediaItemHolder(val adapter: ImagePagerAdapter, itemView: View) : RecyclerPagerAdapter.ViewHolder(itemView) {
|
||||
private val mediaPreview = itemView.mediaPreview
|
||||
fun display(media: ParcelableMedia) {
|
||||
adapter.requestManager.load(media.preview_url).into(mediaPreview)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val layoutResource = R.layout.adapter_item_large_media_status_preview_item
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val layoutResource = R.layout.adapter_item_large_media_status
|
||||
}
|
||||
}
|
|
@ -38,20 +38,15 @@ import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
|||
|
||||
class MediaStatusViewHolder(private val adapter: IStatusesAdapter, itemView: View) : RecyclerView.ViewHolder(itemView), IStatusViewHolder, View.OnClickListener, View.OnLongClickListener {
|
||||
override val profileImageView: ProfileImageView = itemView.mediaProfileImage
|
||||
override val profileTypeView: ImageView? = null
|
||||
|
||||
private val mediaImageContainer = itemView.mediaImageContainer
|
||||
|
||||
private val mediaImageView = itemView.mediaImage
|
||||
private val mediaTextView = itemView.mediaText
|
||||
|
||||
private val aspectRatioSource = SimpleAspectRatioSource()
|
||||
|
||||
private var listener: IStatusViewHolder.StatusClickListener? = null
|
||||
|
||||
override val profileTypeView: ImageView?
|
||||
get() = null
|
||||
|
||||
|
||||
init {
|
||||
mediaImageContainer.setAspectRatioSource(aspectRatioSource)
|
||||
}
|
||||
|
@ -140,4 +135,8 @@ class MediaStatusViewHolder(private val adapter: IStatusesAdapter, itemView: Vie
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val layoutResource = R.layout.adapter_item_media_status
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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/>.
|
||||
-->
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/itemContent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<org.mariotaku.twidere.view.ProfileImageView
|
||||
android:id="@+id/profileImage"
|
||||
android:layout_width="@dimen/icon_size_large_media_status_profile_image"
|
||||
android:layout_height="@dimen/icon_size_large_media_status_profile_image"
|
||||
android:layout_marginLeft="@dimen/element_spacing_large"
|
||||
android:layout_marginStart="@dimen/element_spacing_large"
|
||||
android:layout_marginTop="@dimen/element_spacing_large"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@mipmap/ic_launcher"/>
|
||||
|
||||
<org.mariotaku.twidere.view.NameView
|
||||
android:id="@+id/nameView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_marginStart="@dimen/element_spacing_normal"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/profileImage"
|
||||
app:layout_constraintStart_toEndOf="@+id/profileImage"
|
||||
app:layout_constraintTop_toTopOf="@+id/profileImage"
|
||||
app:nv_primaryTextColor="?android:textColorPrimary"
|
||||
app:nv_primaryTextStyle="bold"
|
||||
app:nv_secondaryTextColor="?android:textColorSecondary"
|
||||
tools:text="Username"/>
|
||||
|
||||
<org.mariotaku.twidere.view.ExtendedViewPager
|
||||
android:id="@+id/mediaPreviewPager"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="@dimen/element_spacing_large"
|
||||
app:layout_constraintDimensionRatio="1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/profileImage"
|
||||
tools:background="@drawable/nyan_stars_background"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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/>.
|
||||
-->
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/mediaPreview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
</FrameLayout>
|
|
@ -80,6 +80,7 @@
|
|||
<dimen name="icon_size_profile_type_detail">22dp</dimen>
|
||||
<dimen name="icon_size_profile_type_user_profile">26dp</dimen>
|
||||
<dimen name="icon_size_status_profile_image">48dp</dimen>
|
||||
<dimen name="icon_size_large_media_status_profile_image">32dp</dimen>
|
||||
<dimen name="icon_size_user_profile">84dp</dimen>
|
||||
<dimen name="icon_size_conversation_info">64dp</dimen>
|
||||
|
||||
|
|
Loading…
Reference in New Issue