feat: 部分界面适配平板界面

This commit is contained in:
HuanCheng65 2022-04-09 20:52:33 +08:00
parent 8bb034ebaa
commit 53c28e4cfa
13 changed files with 153 additions and 27 deletions

View File

@ -5,6 +5,7 @@ import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.content.res.Configuration
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
@ -90,3 +91,9 @@ fun ViewGroup.enableChangingLayoutTransition() {
fun View.getLocationInWindow(): IntArray { fun View.getLocationInWindow(): IntArray {
return IntArray(2).apply { getLocationInWindow(this) } return IntArray(2).apply { getLocationInWindow(this) }
} }
val Configuration.isPortrait: Boolean
get() = orientation == Configuration.ORIENTATION_PORTRAIT
val Configuration.isLandscape: Boolean
get() = orientation == Configuration.ORIENTATION_LANDSCAPE

View File

@ -6,6 +6,7 @@ import android.app.Activity
import android.app.Dialog import android.app.Dialog
import android.content.Context import android.content.Context
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
@ -112,6 +113,11 @@ abstract class BaseActivity : SwipeBackActivity(), ExtraRefreshable, CoroutineSc
} }
} }
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
getDeviceDensity()
}
private fun fixBackground() { private fun fixBackground() {
val decor = window.decorView as ViewGroup val decor = window.decorView as ViewGroup
val decorChild = decor.getChildAt(0) as ViewGroup val decorChild = decor.getChildAt(0) as ViewGroup

View File

@ -54,14 +54,14 @@ class MainForumListAdapter(
viewHolder.itemView.backgroundTintList = ColorStateListUtils.createColorStateList(context, R.color.default_color_card) viewHolder.itemView.backgroundTintList = ColorStateListUtils.createColorStateList(context, R.color.default_color_card)
} }
} }
//双列左 //多列第一个
position % spanCount == 0 -> { position % spanCount == 0 -> {
viewHolder.itemView.backgroundTintList = ColorStateListUtils.createColorStateList(context, R.color.default_color_card) viewHolder.itemView.backgroundTintList = ColorStateListUtils.createColorStateList(context, R.color.default_color_card)
viewHolder.itemView.background = wrapRipple( viewHolder.itemView.background = wrapRipple(
Util.getColorByAttr(context, R.attr.colorControlHighlight, R.color.transparent), Util.getColorByAttr(context, R.attr.colorControlHighlight, R.color.transparent),
when (position) { when (position) {
//最后一行,左 //最后一行,左
getCount() - 2 -> getRadiusDrawable(bottomLeftPx = cardRadius) getCount() - spanCount -> getRadiusDrawable(bottomLeftPx = cardRadius)
//最后一项 //最后一项
getCount() - 1 -> getRadiusDrawable(bottomLeftPx = cardRadius, bottomRightPx = cardRadius) getCount() - 1 -> getRadiusDrawable(bottomLeftPx = cardRadius, bottomRightPx = cardRadius)
//其他 //其他
@ -69,7 +69,7 @@ class MainForumListAdapter(
} }
) )
} }
//列右 //列右
else -> { else -> {
viewHolder.itemView.backgroundTintList = ColorStateListUtils.createColorStateList(context, R.color.default_color_card) viewHolder.itemView.backgroundTintList = ColorStateListUtils.createColorStateList(context, R.color.default_color_card)
viewHolder.itemView.background = wrapRipple( viewHolder.itemView.background = wrapRipple(

View File

@ -13,6 +13,7 @@ import androidx.gridlayout.widget.GridLayout;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.huanchengfly.tieba.post.BaseApplication; import com.huanchengfly.tieba.post.BaseApplication;
import com.huanchengfly.tieba.post.ExtensionsKt;
import com.huanchengfly.tieba.post.R; import com.huanchengfly.tieba.post.R;
import com.huanchengfly.tieba.post.api.models.ForumPageBean; import com.huanchengfly.tieba.post.api.models.ForumPageBean;
import com.huanchengfly.tieba.post.api.models.PersonalizedBean; import com.huanchengfly.tieba.post.api.models.PersonalizedBean;
@ -69,11 +70,19 @@ public class PersonalizedFeedAdapter extends MultiBaseAdapter<PersonalizedBean.T
} }
private int getMaxWidth() { private int getMaxWidth() {
return BaseApplication.ScreenInfo.EXACT_SCREEN_WIDTH - DisplayUtil.dp2px(mContext, 56); int maxWidth = BaseApplication.ScreenInfo.EXACT_SCREEN_WIDTH - DisplayUtil.dp2px(mContext, 56);
if (mContext.getResources().getBoolean(R.bool.is_tablet)) {
if (ExtensionsKt.isLandscape(mContext.getResources().getConfiguration())) {
return maxWidth / 3;
} else {
return maxWidth / 2;
}
}
return maxWidth;
} }
private int getGridHeight() { private int getGridHeight() {
return (BaseApplication.ScreenInfo.EXACT_SCREEN_WIDTH - DisplayUtil.dp2px(mContext, 56)) / 3; return getMaxWidth() / 3;
} }
private RelativeLayout.LayoutParams getLayoutParams(RelativeLayout.LayoutParams layoutParams) { private RelativeLayout.LayoutParams getLayoutParams(RelativeLayout.LayoutParams layoutParams) {

View File

@ -1,7 +1,6 @@
package com.huanchengfly.tieba.post.adapters.base package com.huanchengfly.tieba.post.adapters.base
import android.content.Context import android.content.Context
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.alibaba.android.vlayout.LayoutHelper import com.alibaba.android.vlayout.LayoutHelper
import com.huanchengfly.tieba.post.components.MyViewHolder import com.huanchengfly.tieba.post.components.MyViewHolder
@ -29,12 +28,12 @@ abstract class BaseMultiTypeDelegateAdapter<Item> @JvmOverloads constructor(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder = MyViewHolder(context, getItemLayoutId(viewType)) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder = MyViewHolder(context, getItemLayoutId(viewType))
override fun onBindViewHolder(holder: MyViewHolder, position: Int) { override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.setItemOnClickListener(View.OnClickListener { holder.setItemOnClickListener {
onItemClickListener?.onClick(holder, getItem(position), position) onItemClickListener?.onClick(holder, getItem(position), position)
}) }
holder.setItemOnLongClickListener(View.OnLongClickListener { holder.setItemOnLongClickListener {
onItemLongClickListener?.onLongClick(holder, getItem(position), position) ?: false onItemLongClickListener?.onLongClick(holder, getItem(position), position) ?: false
}) }
convert(holder, getItem(position), position, getItemViewType(position)) convert(holder, getItem(position), position, getItemViewType(position))
} }

View File

@ -1,5 +1,7 @@
package com.huanchengfly.tieba.post.adapters.forum; package com.huanchengfly.tieba.post.adapters.forum;
import static com.huanchengfly.tieba.post.activities.PhotoViewActivity.OBJ_TYPE_FORUM_PAGE;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.text.TextUtils; import android.text.TextUtils;
@ -13,7 +15,9 @@ import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView; import androidx.cardview.widget.CardView;
import androidx.gridlayout.widget.GridLayout; import androidx.gridlayout.widget.GridLayout;
import com.alibaba.android.vlayout.LayoutHelper;
import com.alibaba.android.vlayout.layout.LinearLayoutHelper; import com.alibaba.android.vlayout.layout.LinearLayoutHelper;
import com.alibaba.android.vlayout.layout.StaggeredGridLayoutHelper;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.huanchengfly.tieba.post.BaseApplication; import com.huanchengfly.tieba.post.BaseApplication;
import com.huanchengfly.tieba.post.R; import com.huanchengfly.tieba.post.R;
@ -43,8 +47,6 @@ import java.util.Objects;
import cn.jzvd.Jzvd; import cn.jzvd.Jzvd;
import static com.huanchengfly.tieba.post.activities.PhotoViewActivity.OBJ_TYPE_FORUM_PAGE;
public class NewForumAdapter extends BaseMultiTypeDelegateAdapter<ForumPageBean.ThreadBean> { public class NewForumAdapter extends BaseMultiTypeDelegateAdapter<ForumPageBean.ThreadBean> {
public static final String TAG = NewForumAdapter.class.getSimpleName(); public static final String TAG = NewForumAdapter.class.getSimpleName();
public static final int TYPE_THREAD_COMMON = 11; public static final int TYPE_THREAD_COMMON = 11;
@ -55,6 +57,16 @@ public class NewForumAdapter extends BaseMultiTypeDelegateAdapter<ForumPageBean.
private Map<String, ForumPageBean.UserBean> userBeanMap; private Map<String, ForumPageBean.UserBean> userBeanMap;
private List<Long> ids; private List<Long> ids;
@NonNull
@Override
public LayoutHelper onCreateLayoutHelper() {
if (getContext().getResources().getBoolean(R.bool.is_tablet)) {
return new StaggeredGridLayoutHelper(2);
} else {
return new LinearLayoutHelper();
}
}
public NewForumAdapter(Context context) { public NewForumAdapter(Context context) {
super(context, new LinearLayoutHelper()); super(context, new LinearLayoutHelper());
ids = new ArrayList<>(); ids = new ArrayList<>();
@ -73,11 +85,19 @@ public class NewForumAdapter extends BaseMultiTypeDelegateAdapter<ForumPageBean.
} }
private int getMaxWidth() { private int getMaxWidth() {
return BaseApplication.ScreenInfo.EXACT_SCREEN_WIDTH - DisplayUtil.dp2px(getContext(), 40); int maxWidth = BaseApplication.ScreenInfo.EXACT_SCREEN_WIDTH - DisplayUtil.dp2px(getContext(), 40);
if (getContext().getResources().getBoolean(R.bool.is_tablet)) {
return maxWidth / 2;
}
return maxWidth;
} }
private int getGridHeight() { private int getGridHeight() {
return (BaseApplication.ScreenInfo.EXACT_SCREEN_WIDTH - DisplayUtil.dp2px(getContext(), 70)) / 3; int maxWidth = BaseApplication.ScreenInfo.EXACT_SCREEN_WIDTH - DisplayUtil.dp2px(getContext(), 70);
if (getContext().getResources().getBoolean(R.bool.is_tablet)) {
maxWidth = maxWidth / 2;
}
return maxWidth / 3;
} }
private RelativeLayout.LayoutParams getLayoutParams(RelativeLayout.LayoutParams layoutParams) { private RelativeLayout.LayoutParams getLayoutParams(RelativeLayout.LayoutParams layoutParams) {

View File

@ -37,7 +37,14 @@ public class ForumDivider extends RecyclerView.ItemDecoration implements Tintabl
@Override @Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state); super.getItemOffsets(outRect, view, parent, state);
if (mOrientation == LinearLayoutManager.VERTICAL) { int position = parent.getChildAdapterPosition(view) - 1;
if (parent.getResources().getBoolean(R.bool.is_tablet)) {
if (position % 2 == 0) {
outRect.set(0, 0, mDividerHeight / 2, mDividerHeight);
} else {
outRect.set(mDividerHeight / 2, 0, 0, mDividerHeight);
}
} else if (mOrientation == LinearLayoutManager.VERTICAL) {
outRect.set(0, 0, 0, mDividerHeight); outRect.set(0, 0, 0, mDividerHeight);
} else { } else {
outRect.set(0, 0, mDividerHeight, 0); outRect.set(0, 0, mDividerHeight, 0);

View File

@ -12,8 +12,11 @@ import androidx.annotation.CallSuper
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import butterknife.ButterKnife import butterknife.ButterKnife
import butterknife.Unbinder import butterknife.Unbinder
import com.huanchengfly.tieba.post.R
import com.huanchengfly.tieba.post.interfaces.BackHandledInterface import com.huanchengfly.tieba.post.interfaces.BackHandledInterface
import com.huanchengfly.tieba.post.interfaces.Refreshable import com.huanchengfly.tieba.post.interfaces.Refreshable
import com.huanchengfly.tieba.post.isLandscape
import com.huanchengfly.tieba.post.isPortrait
import com.huanchengfly.tieba.post.utils.AppPreferencesUtils import com.huanchengfly.tieba.post.utils.AppPreferencesUtils
import com.huanchengfly.tieba.post.utils.HandleBackUtil import com.huanchengfly.tieba.post.utils.HandleBackUtil
import kotlinx.coroutines.* import kotlinx.coroutines.*
@ -187,6 +190,15 @@ abstract class BaseFragment : Fragment(), BackHandledInterface, CoroutineScope {
} }
} }
protected val isTablet: Boolean
get() = attachContext.resources.getBoolean(R.bool.is_tablet)
protected val isPortrait: Boolean
get() = attachContext.resources.configuration.isPortrait
protected val isLandscape: Boolean
get() = attachContext.resources.configuration.isLandscape
open fun hasOwnAppbar(): Boolean { open fun hasOwnAppbar(): Boolean {
return false return false
} }

View File

@ -77,7 +77,6 @@ class MainForumListFragment : BaseFragment(), Refreshable, Toolbar.OnMenuItemCli
@BindView(R.id.refresh) @BindView(R.id.refresh)
lateinit var mRefreshView: SmartRefreshLayout lateinit var mRefreshView: SmartRefreshLayout
private var navigationHelper: NavigationHelper? = null
private lateinit var delegateAdapter: DelegateAdapter private lateinit var delegateAdapter: DelegateAdapter
private lateinit var virtualLayoutManager: VirtualLayoutManager private lateinit var virtualLayoutManager: VirtualLayoutManager
private lateinit var mainForumListAdapter: MainForumListAdapter private lateinit var mainForumListAdapter: MainForumListAdapter
@ -120,14 +119,19 @@ class MainForumListFragment : BaseFragment(), Refreshable, Toolbar.OnMenuItemCli
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
virtualLayoutManager = VirtualLayoutManager(attachContext) virtualLayoutManager = VirtualLayoutManager(attachContext)
delegateAdapter = DelegateAdapter(virtualLayoutManager) delegateAdapter = DelegateAdapter(virtualLayoutManager)
navigationHelper = NavigationHelper.newInstance(attachContext)
} }
private val spanCount: Int private val spanCount: Int
get() = if (appPreferences.listSingle) { get() = when {
1 appPreferences.listSingle -> {
} else { 1
2 }
resources.getBoolean(R.bool.is_tablet) -> {
3
}
else -> {
2
}
} }
private fun toggleTopForum(forumId: String) { private fun toggleTopForum(forumId: String) {

View File

@ -2,6 +2,7 @@ package com.huanchengfly.tieba.post.fragments
import android.animation.Animator import android.animation.Animator
import android.animation.AnimatorListenerAdapter import android.animation.AnimatorListenerAdapter
import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
@ -10,6 +11,7 @@ import android.widget.Toast
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener import androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import butterknife.BindView import butterknife.BindView
import cn.jzvd.Jzvd import cn.jzvd.Jzvd
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
@ -22,8 +24,11 @@ import com.huanchengfly.tieba.post.api.models.PersonalizedBean
import com.huanchengfly.tieba.post.api.retrofit.exception.TiebaException import com.huanchengfly.tieba.post.api.retrofit.exception.TiebaException
import com.huanchengfly.tieba.post.components.MyLinearLayoutManager import com.huanchengfly.tieba.post.components.MyLinearLayoutManager
import com.huanchengfly.tieba.post.components.dividers.FeedDivider import com.huanchengfly.tieba.post.components.dividers.FeedDivider
import com.huanchengfly.tieba.post.components.dividers.StaggeredDividerItemDecoration
import com.huanchengfly.tieba.post.goToActivity import com.huanchengfly.tieba.post.goToActivity
import com.huanchengfly.tieba.post.interfaces.Refreshable import com.huanchengfly.tieba.post.interfaces.Refreshable
import com.huanchengfly.tieba.post.isLandscape
import com.huanchengfly.tieba.post.isPortrait
import com.huanchengfly.tieba.post.utils.* import com.huanchengfly.tieba.post.utils.*
import com.huanchengfly.tieba.post.widgets.ShadowLayout import com.huanchengfly.tieba.post.widgets.ShadowLayout
import com.huanchengfly.tieba.post.widgets.VideoPlayerStandard import com.huanchengfly.tieba.post.widgets.VideoPlayerStandard
@ -65,7 +70,7 @@ class PersonalizedFeedFragment : BaseFragment(), PersonalizedFeedAdapter.OnRefre
override fun hasOwnAppbar(): Boolean = true override fun hasOwnAppbar(): Boolean = true
public override fun getLayoutId(): Int = R.layout.fragment_personalized_feed override fun getLayoutId(): Int = R.layout.fragment_personalized_feed
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@ -84,7 +89,6 @@ class PersonalizedFeedFragment : BaseFragment(), PersonalizedFeedAdapter.OnRefre
onRefreshListener = this@PersonalizedFeedFragment onRefreshListener = this@PersonalizedFeedFragment
} }
recyclerView.apply { recyclerView.apply {
addItemDecoration(FeedDivider(attachContext))
if (!appPreferences.loadPictureWhenScroll) { if (!appPreferences.loadPictureWhenScroll) {
addOnScrollListener(object : RecyclerView.OnScrollListener() { addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
@ -105,20 +109,51 @@ class PersonalizedFeedFragment : BaseFragment(), PersonalizedFeedAdapter.OnRefre
addOnChildAttachStateChangeListener(object : OnChildAttachStateChangeListener { addOnChildAttachStateChangeListener(object : OnChildAttachStateChangeListener {
override fun onChildViewAttachedToWindow(view: View) {} override fun onChildViewAttachedToWindow(view: View) {}
override fun onChildViewDetachedFromWindow(view: View) { override fun onChildViewDetachedFromWindow(view: View) {
val videoPlayerStandard: VideoPlayerStandard? = view.findViewById(R.id.forum_item_content_video) val videoPlayerStandard: VideoPlayerStandard? =
view.findViewById(R.id.forum_item_content_video)
if (videoPlayerStandard != null && Jzvd.CURRENT_JZVD != null && if (videoPlayerStandard != null && Jzvd.CURRENT_JZVD != null &&
videoPlayerStandard.jzDataSource.containsTheUrl(Jzvd.CURRENT_JZVD.jzDataSource.currentUrl)) { videoPlayerStandard.jzDataSource.containsTheUrl(Jzvd.CURRENT_JZVD.jzDataSource.currentUrl)
) {
if (Jzvd.CURRENT_JZVD != null && Jzvd.CURRENT_JZVD.screen != Jzvd.SCREEN_FULLSCREEN) { if (Jzvd.CURRENT_JZVD != null && Jzvd.CURRENT_JZVD.screen != Jzvd.SCREEN_FULLSCREEN) {
Jzvd.releaseAllVideos() Jzvd.releaseAllVideos()
} }
} }
} }
}) })
layoutManager = MyLinearLayoutManager(attachContext) layoutManager = if (!isTablet) {
addItemDecoration(FeedDivider(attachContext))
MyLinearLayoutManager(attachContext)
} else {
addItemDecoration(StaggeredDividerItemDecoration(attachContext, 12))
StaggeredGridLayoutManager(getSpanCount(), StaggeredGridLayoutManager.VERTICAL)
}
adapter = this@PersonalizedFeedFragment.adapter adapter = this@PersonalizedFeedFragment.adapter
} }
} }
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
if (recyclerView.layoutManager is StaggeredGridLayoutManager) {
(recyclerView.layoutManager as StaggeredGridLayoutManager).spanCount =
getSpanCount(newConfig)
}
}
private fun getSpanCount(configuration: Configuration = attachContext.resources.configuration): Int {
return when {
isTablet && configuration.isPortrait -> {
2
}
isTablet && configuration.isLandscape -> {
3
}
else -> {
1
}
}
}
fun refresh() { fun refresh() {
page = 1 page = 1
TiebaApi.getInstance().personalized(1, page).enqueue(object : Callback<PersonalizedBean> { TiebaApi.getInstance().personalized(1, page).enqueue(object : Callback<PersonalizedBean> {

View File

@ -0,0 +1,3 @@
<resources>
<bool name="is_tablet">true</bool>
</resources>

View File

@ -0,0 +1,21 @@
<resources>
<style name="Widget.TabLayout.Toolbar.Fixed" parent="Widget.TabLayout.Toolbar">
<item name="paddingStart">5dp</item>
<item name="paddingEnd">5dp</item>
<item name="tabPaddingStart">16dp</item>
<item name="tabPaddingEnd">16dp</item>
<item name="tabUnboundedRipple">false</item>
<item name="tabRippleColor">@color/transparent</item>
<item name="tabMode">fixed</item>
<item name="tabGravity">fill</item>
<item name="tabMaxWidth">0dp</item>
<item name="tabTextColor">@color/default_color_toolbar_item_secondary</item>
<item name="tabSelectedTextColor">@color/default_color_toolbar_item</item>
<item name="tabBackground">@color/transparent</item>
<item name="tabIndicatorFullWidth">true</item>
<item name="tabIndicatorGravity">center</item>
<item name="tabIndicator">@drawable/drawable_tab_indicator_new</item>
<item name="tabIndicatorColor">@color/default_color_toolbar</item>
</style>
</resources>

View File

@ -0,0 +1,3 @@
<resources>
<bool name="is_tablet">false</bool>
</resources>