具有相同功能的活动和片段

Posted

技术标签:

【中文标题】具有相同功能的活动和片段【英文标题】:Activities and fragments with the same features 【发布时间】:2021-12-05 14:34:37 【问题描述】:

我有相同的 UI 相关功能和实现,我想在 ActivityFragment 中使用一次。如何实现架构以避免重复代码?

Activity 中显示Fragment 会降低性能吗?

我的目标是为其他类实现一个abstract class 以使用分页。子类有时是Activity 类型,有时是Fragment 类型。

我设计了一个interface,它具有以下方法。然后我在abstract Fragment 类中实现了这些功能:

public interface PaginableComponent 

void onRequestList();

void onSuccessLoadList(@NonNull List<Paginable> list);

void onErrorLoadList(String errorMessage);

void onRequestLoadMoreList(int oldTotalCount);

void onSuccessLoadMore(@NonNull List<Paginable> list);

void onTryLoadList();

@NonNull
PaginableAdapter getAdapter();

这是实现此接口的abstract Fragment 类:

public abstract class PaginableFragment extends BaseFragment
    implements PaginableComponent, PaginableAdapter.LoadListMoreListener 


private final AtomicBoolean mIsFirstLoadedList = new 
AtomicBoolean(false);

private SwipeRefreshLayout mSwipeRefreshLayout;
private View mStatusLayout;
private ProgressBar mStatusProgressBar;
private TextView mStatusMessageTextView;
private TextView mTryAgainTextView;

public Boolean isHidden = true;

@CallSuper
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) 
    super.onViewCreated(view, savedInstanceState);
    initViews(view);
    getAdapter().setLoadListMoreListener(this);
    if (mSwipeRefreshLayout != null) 
        mSwipeRefreshLayout.setColorSchemeColors(UiUtils.getStyleColor(requireContext(), R.attr.colorPrimary));
        mSwipeRefreshLayout.setOnRefreshListener(this::checkNetAndRequestList);
    


@Override
public void onPause() 
    super.onPause();
    isHidden = true;


@Override
public void onResume() 
    super.onResume();
    isHidden = isHidden();


@Override
public void onHiddenChanged(boolean hidden) 
    super.onHiddenChanged(hidden);
    isHidden = hidden;


private void initViews(View view) 
    mSwipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout);
    mStatusLayout = view.findViewById(R.id.statusLayout);
    if (mStatusLayout != null) 
        mStatusProgressBar = mStatusLayout.findViewById(R.id.progressBar);
        mStatusMessageTextView = mStatusLayout.findViewById(R.id.text);
        mTryAgainTextView = mStatusLayout.findViewById(R.id.tryAgain);
        mTryAgainTextView.setOnClickListener(v -> onTryLoadList());
    


protected void showStatus(String type) 
    if (mStatusLayout != null) 
        switch (type) 
            case Messages.MSG_LOADING:
                mStatusProgressBar.setVisibility(View.VISIBLE);
                mStatusMessageTextView.setVisibility(View.GONE);
                mTryAgainTextView.setVisibility(View.GONE);
                break;
            case Messages.MSG_NET:
                mStatusMessageTextView.setText(R.string.no_network_connection);
                mStatusProgressBar.setVisibility(View.GONE);
                mStatusMessageTextView.setVisibility(View.VISIBLE);
                mTryAgainTextView.setVisibility(View.VISIBLE);
                break;
            case Messages.MSG_ERROR:
                mStatusMessageTextView.setText(R.string.sorry_unexpected_error_occurred);
                mStatusProgressBar.setVisibility(View.GONE);
                mStatusMessageTextView.setVisibility(View.VISIBLE);
                mTryAgainTextView.setVisibility(View.GONE);
                break;
        
        mStatusLayout.setVisibility(View.VISIBLE);
    


private void hideStatus() 
    if (mStatusLayout != null) 
        mStatusLayout.setVisibility(View.GONE);
    


@CallSuper
@Override
public void onSuccessLoadList(@NonNull List<Paginable> list) 
    mIsFirstLoadedList.set(true);
    if (mSwipeRefreshLayout != null) 
        mSwipeRefreshLayout.setRefreshing(false);
    
    hideStatus();
    getAdapter().resetList(list);


@CallSuper
@Override
public void onErrorLoadList(String errorMessage) 
    if (mSwipeRefreshLayout != null) 
        mSwipeRefreshLayout.setRefreshing(false);
    
    showStatus(Messages.MSG_ERROR);
    getAdapter().setIsLoadingMore(false);


@CallSuper
@Override
public void onLoadListMore(int oldTotalCount) 
    getAdapter().showEndMessage(Paginable.TYPE_SHIMMER);
    if (NetReceiver.isNetConnected(requireContext())) 
        onRequestLoadMoreList(oldTotalCount);
     else 
        showStatus(Messages.MSG_NET);
    


@CallSuper
@Override
public void onSuccessLoadMore(@NonNull List<Paginable> list) 
    if (mSwipeRefreshLayout != null) 
        mSwipeRefreshLayout.setRefreshing(false);
    
    hideStatus();
    getAdapter().hideEndMessages();
    getAdapter().addList(list);
    getAdapter().setIsLoadingMore(false);


@CallSuper
@Override
public void onTryLoadList() 
    if (!mIsFirstLoadedList.get()) 
        checkNetAndRequestList();
    


@Override
public void onNetEvent(NetReceiver.NetEvent event) 
    if (event.isConnected()) 
        hideStatus();
        if (!mIsFirstLoadedList.get()) 
            getAdapter().clearAndInitShimmers();
            onRequestList();
        
        if (getAdapter().isLoadingMore()) 
            onRequestLoadMoreList(getAdapter().getItemCount());
        
     else 
        showStatus(Messages.MSG_NET);
    


public void checkNetAndRequestList() 
    if (NetReceiver.isNetConnected(requireContext())) 
        if (!mIsFirstLoadedList.get()) 
            getAdapter().clearAndInitShimmers();
        
        onRequestList();
     else 
        if (mSwipeRefreshLayout != null) 
            mSwipeRefreshLayout.setRefreshing(false);
        
        showStatus(Messages.MSG_NET);
        if (!mIsFirstLoadedList.get()) 
            getAdapter().clearAndInitNoInternet();
        
    


现在我想在活动中使用相同的实现。

【问题讨论】:

我认为你应该检查the guidelines on how to ask questions use once in Activity and again in Fragment 这意味着你在活动中真的不需要它,你只需要使用相同的片段两次,对吧? Does displaying a Fragment in an Activity reduce performance? 为什么会这样?它会产生足够的改变来改变任何东西吗?没有 【参考方案1】:

防止重复代码的一种方法是在 MVVM 架构中使用 ViewModelLiveData

【讨论】:

但是我的大部分代码都和UI实现有关。

以上是关于具有相同功能的活动和片段的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 相同片段多个活动

从活动向上导航到片段打开相同的片段 - Android 导航组件

在 TabLayout 和 ViewPager2 中执行异步任务后更新具有相同布局的多个片段

将相同的图库图像加载到两个不同的活动片段中 Android Picasso

具有相同布局的多个片段

在一个活动中加载单个片段两次,从本地json文件中加载2个问题