getQuantityString

本文介绍Android中如何使用复数字符串资源,以适应不同语言的语法特性,特别是针对数量变化的表述。通过XML文件定义不同数量级对应的字符串,并演示了如何在代码中调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Quantity Strings(复数)

不同的语言对数量进行描述的语法规则也不同。比如在英语里,数量1是个特殊情况,我们写成“1 book”,但其他任何数量都要写成n books”。这种单复数之间的区别是很普遍的,不过其他语言会有更好的区分方式。Android支持的全集包括zeroone twofewmanyother

决定选择和使用某种语言和复数的规则是非常复杂的,所以Android提供了诸如getQuantityString()的方法来选择合适的资源。

注意,要按照语法规则来建立可选项。在英语里,即使数量为0,字符串零(zero)也不需要建立。因为0在英语语法表达上和2没有区别,和其他除1以外的任何数字都没有差别("zero books", "one book", "two books",等等)。 不要被two听起来似乎只能用于数量2” 样的事误导。某语言可能需要212102(等等)和1一样形式表示,而又与其他数的形式都不同。请依靠翻译人员来了解一下实际语言中的差别。

如果和应用程序的风格一致,常可以用诸如“Books: 1”的模糊数量形式来避免使用数量字符串。这会让你和翻译人员都轻松些。

注意:复数字符串是简单类型资源,是用名称(name)(而不是XML文件名)来直接引用的。因此,在一个XML文件里,可以把复数字符串资源和其他简单类型资源一起放在一个<resources>元素下。

 

文件位置

res/values/filename.xml

文件名可随意指定。<plurals>元素的名字name将被用作资源ID

 

资源引用

Java代码:R.plurals.plural_name

 

语法

<?xml version="1.0" encoding="utf-8"?> 

<resources>

<plurals

name="plural_name">

<item_plurals

quantity=["zero" | "one" | "two" | "few" | "many" | "other"

>text_string</item>

</plurals>

</resources>

 

元素

<resources>

必填项必须是根元素。

无属性。

 

<plurals>

一个字符串集,每个数量表示提供一个字符串。包含一个或多个<item>元素。

 

属性:

name

String类型。字符串对的名称。此名称将作为资源ID

<item>

一个单数或复数形式的字符串。可以是对其他字符串资源的引用。必须作为<plurals>元素的子元素存在。注意须对单引号和双引号进行转义。有关如何正确地样式化及格式化字符串,请参阅下文格式化和样式

 

属性:

quantity

关键字 表示要使用此字符串的数量值。以下是合法的值(括号内列出部分语言要求):

描述

zero

语言需要对数字0进行特殊处理。(比如阿拉伯语)

one

语言需要对类似1的数字进行特殊处理。(比如英语和其它大多数语言里的1;在俄语里,任何以1结尾但不以11结尾的数也属于此类型。)

two

语言需要对类似2的数字进行特殊处理。(比如威尔士语)

few

语言需要对较小数字进行特殊处理(比如捷克语里的234;或者波兰语里以234结尾但不是121314的数。)

many

语言需要对较大数字进行特殊处理(比如马耳他语里以11-99结尾的数)

other

语言不需要对数字进行特殊处理。

示例

存放在res/values/strings.xml XML文件:

<?xml version="1.0" encoding="utf-8"?>

<resources>

<plurals name="numberOfSongsAvailable">

<item quantity="one">One song found.</item>

<item quantity="other">%d songs found.</item>

</plurals>

</resources>

 

存放在res/values-pl/strings.xml XML文件:

<?xml version="1.0" encoding="utf-8"?>

<resources>

<plurals name="numberOfSongsAvailable">

<item quantity="one">Znaleziono jedną piosenkę.</item>

<item quantity="few">Znaleziono %d piosenki.</item>

<item quantity="other">Znaleziono %d piosenek.</item>

</plurals>

</resources>

 

Java代码:

int count = getNumberOfsongsAvailable(); 

Resources res = getResources(); 

String songsFound = res.getQuantityString(R.plurals.numberOfSongsAvailable, count,count);

 

在使用getQuantityString()方法时,如果字符串包含数字格式化串,则需要传递2count参数。例如:对于字符串%d songs found”,第一个count参数选择合适的复数字符串,第二个count参数插入占位符%d中。如果复数字符串资源不包含格式化信息,就不需要给getQuantityString()传递第三个参数。


原文:http://www.cnblogs.com/meiyitian/articles/2221742.html

/********************************************************************* * * Copyright (C), 2010-2022 Oplus. All rights reserved.. * * VENDOR_EDIT * * File : AddFilePanelFragment.kt * * Description : AddFilePanelFragment * * Version : 1.0 * * Date : 2025/02/08 * * Author : W9085798 * * * * ---------------------Revision History: ---------------------------- * * <author> <data> <version> <desc> ***********************************************************************/ package com.oplus.filemanager.addfilepanel.ui import android.annotation.SuppressLint import android.app.Activity import android.os.SystemClock import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.RelativeLayout import android.widget.TextView import androidx.annotation.VisibleForTesting import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelProvider import com.coui.appcompat.button.COUIButton import com.coui.appcompat.button.SingleButtonWrap import com.coui.appcompat.contextutil.COUIContextUtil import com.coui.appcompat.panel.COUIBottomSheetDialog import com.coui.appcompat.panel.COUIBottomSheetDialogFragment import com.coui.appcompat.panel.COUIPanelFragment import com.coui.appcompat.panel.COUIPanelMultiWindowUtils import com.coui.appcompat.tablayout.COUITab import com.coui.appcompat.tablayout.COUITabLayout import com.coui.appcompat.toolbar.COUIToolbar import com.filemanager.common.MyApplication.appContext import com.filemanager.common.base.BaseFileBean import com.filemanager.common.base.BaseFragmentAdapter import com.filemanager.common.constants.Constants import com.filemanager.common.controller.LoadingController import com.filemanager.common.controller.PrivacyPolicyController import com.filemanager.common.helper.MimeTypeHelper import com.filemanager.common.helper.uiconfig.UIConfigMonitor import com.filemanager.common.utils.Injector import com.filemanager.common.utils.KtViewUtils import com.filemanager.common.utils.Log import com.filemanager.common.utils.ModelUtils import com.filemanager.common.utils.SdkUtils import com.filemanager.common.utils.StatusBarUtil import com.filemanager.common.utils.Utils import com.filemanager.common.utils.dp2px import com.filemanager.common.view.ViewPagerWrapperForPC import com.filemanager.common.view.viewpager.RTLViewPager import com.oplus.filemanager.addfilepanel.R import com.oplus.filemanager.addfilepanel.bean.AddFileBean import com.oplus.filemanager.addfilepanel.viewmodel.AddFilePanelViewModel import com.oplus.filemanager.interfaze.categorydoc.IDocumentExtensionType import com.oplus.filemanager.interfaze.main.IMain import kotlin.properties.Delegates class AddFilePanelFragment : COUIPanelFragment(), COUITabLayout.OnTabSelectedListener, PrivacyPolicyController.OnPrivacyPolicyListener { companion object { private const val TAG = "ShortcutFolderAddFilePanelFragment" private const val NUM = 1024 private const val DECIMAL_NUM = 1024f private const val DISMISS_TIME_GAP = 1000L private const val DELAY_TIME = 50L private const val PANEL_MAX_HEIGHT = "panel_max_height" } var lifeCycle: Lifecycle by Delegates.notNull() var title: String? = null var mCurrentPath: String = "" private var disMissTime: Long = 0L private var toolBar: COUIToolbar? = null private var mTabTitle = arrayListOf( appContext.resources.getString(com.filemanager.common.R.string.total), appContext.resources.getString(com.filemanager.common.R.string.string_photos), appContext.resources.getString(com.filemanager.common.R.string.string_videos), appContext.resources.getString(com.filemanager.common.R.string.string_audio), appContext.resources.getString(com.filemanager.common.R.string.string_documents), appContext.resources.getString(com.filemanager.common.R.string.string_other) ) private val mTabTitles = intArrayOf( Constants.TAB_ALL, Constants.TAB_IMAGE, Constants.TAB_VIDEO, Constants.TAB_AUDIO, Constants.TAB_DOCUMENT, Constants.TAB_OTHER ) private var mAddFileDialogInterface: AddFileDialogInterface? = null private var mPages: ArrayList<AddFileListFragment> = ArrayList() private var mViewPager: RTLViewPager? = null private var mTabView: COUITabLayout? = null private var mViewPagerWrapper: ViewPagerWrapperForPC? = null private var addFileBtn: COUIButton? = null private var verticalButtonWrap: SingleButtonWrap? = null private var rootView: ViewGroup? = null private var addFilePanelViewModel: AddFilePanelViewModel? = null private var statisticsSelectTitleView: TextView? = null private var statisticsSelectBodyView: TextView? = null private var contentLayout: RelativeLayout? = null private var buttonDivider: View? = null private var statisticsArrowUpView: ImageView? = null private var statisticsRootView: ViewGroup? = null private var loadingController: LoadingController? = null private var mPosition: Int = 0 var limitCount: Int = 0 private val allFiles: MutableList<BaseFileBean> = mutableListOf() private val imageFiles: MutableList<BaseFileBean> = mutableListOf() private val videoFiles: MutableList<BaseFileBean> = mutableListOf() private val audioFiles: MutableList<BaseFileBean> = mutableListOf() private val docFiles: MutableList<BaseFileBean> = mutableListOf() private val otherFiles: MutableList<BaseFileBean> = mutableListOf() private val mSelectArrayByID: MutableSet<Long> = mutableSetOf() var addFileClickCallback: (selectData: List<AddFileBean>) -> Unit = {} var isExternalReference: Boolean = false private fun setPanelMaxHeight() { if (activity == null) return rootView?.layoutParams?.apply { if (UIConfigMonitor.isCurrentZoomWindowShow() && SdkUtils.isAtLeastR() && !isExternalReference) { val savedHeight: Int = arguments?.getInt(PANEL_MAX_HEIGHT) ?: 0 Log.d(TAG, "setPanelMaxHeight savedHeight = $savedHeight") if (savedHeight == 0) { // 处理浮窗 height = handleZoomWindowHeight(requireActivity(), height) arguments?.putInt(PANEL_MAX_HEIGHT, height) } else { height = savedHeight } Log.d(TAG, "setPanelMaxHeight height = $height") } else { val screenHeight = dp2px(requireActivity(), requireActivity().resources.configuration.screenHeightDp) val panelMaxHeight = COUIPanelMultiWindowUtils.getPanelMaxHeight(requireActivity(), requireActivity().resources.configuration) Log.d(TAG, "setPanelMaxHeight screenHeight:$screenHeight panelH:$panelMaxHeight height:$height") //当是分屏 if (requireActivity().isInMultiWindowMode) { if (StatusBarUtil.checkIsGestureNavMode(requireActivity())) { //全面屏手势导航 height = handleGestureNavModeHeight(requireActivity(), height) } else { // 底部导航栏 height = Math.min(screenHeight, panelMaxHeight) - requireActivity().resources.getDimensionPixelOffset( com.filemanager.common.R.dimen.dimen_40dp ) height = handleNavModeHeight(requireActivity(), height) } } rootView?.layoutParams = this } } } /** * 处理浮窗模式下的高度 */ private fun handleZoomWindowHeight(activity: Activity, height: Int): Int { var result = height val statusBarH = COUIPanelMultiWindowUtils.getStatusBarHeight(activity) val configuration = activity.resources.configuration val paddingBottom = COUIPanelMultiWindowUtils.getPanelMarginBottom(context, configuration) val rect = COUIPanelMultiWindowUtils.getCurrentWindowVisibleRect(activity) if (rect != null) { if (rect.top == 0) { Log.d(TAG, "handleZoomWindowHeight: rect $rect top is invalid, reset") rect.top = activity.resources.getDimensionPixelOffset(com.filemanager.common.R.dimen.panel_min_top_margin) } if (rect.bottom == 0) { val windowH = KtViewUtils.getWindowSize(activity).y rect.bottom = windowH Log.d(TAG, "handleZoomWindowHeight: rect $rect bottom is invalid, reset $windowH") } result = (rect.bottom - rect.top) - paddingBottom - statusBarH Log.d(TAG, "handleZoomWindowHeight: height $result = ${rect.bottom}-${rect.top}-$paddingBottom-$statusBarH") } return result } /** * 处理底部导航栏导航时的高度 */ private fun handleNavModeHeight(it: Activity, height: Int): Int { val navBarHeight = KtViewUtils.getSoftNavigationBarSize(it) var result = height when { ModelUtils.isTablet() -> { //平板竖屏分屏时 if (UIConfigMonitor.instance.isDevicePortrait(it)) { result = height - navBarHeight Log.d(TAG, "handleNavMode pad portrait height:$result") } } UIConfigMonitor.instance.isFoldable(it) -> { // 折叠屏 result = height - navBarHeight Log.d(TAG, "handleNavMode fold height:$result") } else -> { //手机且分屏处于下屏 if (!COUIPanelMultiWindowUtils.isDisplayInUpperWindow(it)) { result = height - navBarHeight Log.d(TAG, "handleNavMode phone lower split screen height:$result") } } } return result } /** * 处理全面屏手势导航时的高度 */ @VisibleForTesting fun handleGestureNavModeHeight(activity: Activity, height: Int): Int { if (COUIPanelMultiWindowUtils.isDisplayInUpperWindow(activity)) { // 上分屏,不用处理 return height } // 处于下分屏,并且显示了手势指示条 if (StatusBarUtil.checkShowGestureNavBar(activity)) { val result = height - activity.resources.getDimensionPixelOffset(com.filemanager.common.R.dimen.dimen_16dp) Log.d(TAG, "handleGestureNavMode lower split screen with show gesture nvaBar height:$result") return result } return height } override fun onDestroy() { Log.d(TAG, "onDestroy") super.onDestroy() verticalButtonWrap?.release() clearDataList() addFilePanelViewModel?.onDestroy() } override fun initView(panelView: View?) { activity?.let { activity -> LayoutInflater.from(activity).inflate(getLayoutResId(), null, false)?.let { (contentView as? ViewGroup)?.addView(it) initContentView(it) initViewModel(activity) startObserver() initData() } } } private fun getLayoutResId(): Int { return R.layout.add_file_panel_dialog } private fun initViewModel(act: FragmentActivity) { addFilePanelViewModel = ViewModelProvider(act)[AddFilePanelViewModel::class.java] } private fun startObserver() { addFilePanelViewModel?.mAllFiles?.observe(this) { it ?: return@observe showLoadingView(false) setViewPagerData(it) } addFilePanelViewModel?.mAllSelectFiles?.observe(this) { it ?: return@observe updateStatisticsSelectView(it) } } fun notifyUpdate() { mSelectArrayByID.clear() addFilePanelViewModel?.mAllSelectFiles?.value?.forEach { bean -> if (bean.isSelected) { bean.mFileID?.let { mSelectArrayByID.add(it) } } } getCurrentFragment()?.apply { setSelectedData(mSelectArrayByID) notifyUpdate() } } private fun initContentView(view: View) { Log.d(TAG, "initContentView") hideDragView() rootView = view.findViewById(R.id.dialog_layout) toolBar = view.findViewById(R.id.toolbar) mTabView = view.findViewById<COUITabLayout?>(R.id.tab_layout) mViewPager = view.findViewById(R.id.viewPager) mViewPagerWrapper = view.findViewById<ViewPagerWrapperForPC?>(R.id.view_pager_wrapper).apply { notifyMainViewPager = object : ((Boolean) -> Unit) { override fun invoke(enable: Boolean) { activity?.let { val mainAction = Injector.injectFactory<IMain>() mainAction?.setViewPagerScrollEnabled(it, enable) } } } } addFileBtn = view.findViewById<COUIButton?>(R.id.btn_add_file).apply { verticalButtonWrap = SingleButtonWrap(this, SingleButtonWrap.Type.Small) setOnClickListener { Log.d(TAG, "addFileBtn click. select:${addFilePanelViewModel?.mAllSelectFiles?.value?.size}") val selectList = addFilePanelViewModel?.mAllSelectFiles?.value selectList?.let { addFileClickCallback.invoke(it) } } } contentLayout = view.findViewById(R.id.content_layout) buttonDivider = view.findViewById(R.id.button_divider) statisticsSelectTitleView = view.findViewById<TextView?>(R.id.select_title_content) statisticsSelectBodyView = view.findViewById<TextView?>(R.id.select_body_content) statisticsArrowUpView = view.findViewById(R.id.select_arraw_up) statisticsRootView = view.findViewById<ViewGroup?>(R.id.select_root_view).apply { setOnClickListener { if (Utils.isQuickClick()) { Log.w(TAG, "click too fast, try later") return@setOnClickListener } addFilePanelViewModel?.mAllSelectFiles?.value?.let { mAddFileDialogInterface?.replaceSelectedPanelFragment(it) } } } setPanelMaxHeight() } private fun initData() { initToolBar() resetStatisticsView() val fragments = childFragmentManager.fragments for (i in mTabTitles.indices) { initFragment(i, fragments) } initViewPager() if (PrivacyPolicyController.hasAgreePrivacy()) { loadData() } else { PrivacyPolicyController.bindPrivacyPolicyListener(this) } } private fun loadData() { Log.d(TAG, "loadData") showLoadingView(true) // 加载数据 activity?.let { addFilePanelViewModel?.loadAllFiles(it) } } private fun resetStatisticsView() { addFileBtn?.isEnabled = false statisticsSelectTitleView?.apply { visibility = View.VISIBLE text = appContext.resources.getString(com.filemanager.common.R.string.not_selected_file) } statisticsSelectBodyView?.apply { visibility = View.GONE text = "" } statisticsArrowUpView?.apply { visibility = View.GONE } statisticsRootView?.apply { isClickable = false } } private fun initToolBar() { toolBar?.apply { visibility = View.VISIBLE title = appContext.resources.getString(com.filemanager.common.R.string.encryption_file_select_title) isTitleCenterStyle = true inflateMenu(R.menu.add_file_panel_dialog_menu_bar) menu.findItem(R.id.cancel).setOnMenuItemClickListener { mAddFileDialogInterface?.dismissAddFileDialog() true } } if ((mTabView != null) && (mViewPager != null)) { mTabView?.let { it.setupWithViewPager(mViewPager, false) it.addOnTabSelectedListener(this) it.isUpdateindicatorposition = true } } } fun setAddFileDialogInterface(addFileDialog: AddFileDialogInterface) { mAddFileDialogInterface = addFileDialog } private fun initViewPager() { mViewPager?.let { it.offscreenPageLimit = mTabTitles.size it.adapter = ViewPagerFragmentStateAdapter(this) it.currentItem = 0 it.overScrollMode = View.OVER_SCROLL_NEVER } } private fun initFragment(position: Int, fragments: List<Fragment>): Fragment { Log.d(TAG, "initFragment") var fragment = if (fragments.isEmpty()) null else fragments[position] if (fragment == null) { fragment = AddFileListFragment() fragment.isExternalReference = isExternalReference fragment.lifeCycle = lifeCycle fragment.mOnItemSelectCallback = { _, fileID -> mSelectArrayByID.add(fileID) addFilePanelViewModel?.updateAllSelectFiles(mSelectArrayByID) } fragment.mOnItemUnSelectCallback = { _, fileID -> mSelectArrayByID.remove(fileID) addFilePanelViewModel?.updateAllSelectFiles(mSelectArrayByID) } fragment.mFileEmptyCallback = { isShowEmpty -> handleFileEmptyView(isShowEmpty) } fragment.mCurrentPath = mCurrentPath fragment.limitCount = limitCount } if (fragment is AddFileListFragment) { mPages.add(fragment) } return fragment } private fun handleFileEmptyView(isShowEmptyView: Boolean) { if (isShowEmptyView) { showLoadingView(false) buttonDivider?.alpha = 0F } else { buttonDivider?.alpha = 1F } } private fun showLoadingView(isShow: Boolean) { if (isShow) { Log.d(TAG, "showLoadingView disMissTime $disMissTime") activity?.let { loadingController = LoadingController(it, this) //如果异常loadingView刚刚调用,就不调用显示loadingView,防止loadingView一直显示 Log.d(TAG, "showLoadingView getLoadingShowStartTime ${loadingController?.getLoadingShowStartTime()}") if (SystemClock.elapsedRealtime() - disMissTime >= DISMISS_TIME_GAP || loadingController?.getLoadingShowStartTime() == 0L) { loadingController?.showLoading(contentLayout) } } } else { Log.d(TAG, "showLoadingView dismissLoading") loadingController?.dismissLoading() disMissTime = SystemClock.elapsedRealtime() } } override fun onShow(isShowOnFirstPanel: Boolean?) { super.onShow(isShowOnFirstPanel) ((parentFragment as? COUIBottomSheetDialogFragment)?.dialog as? COUIBottomSheetDialog) ?.setPanelBackgroundTintColor(COUIContextUtil.getAttrColor(context, com.support.appcompat.R.attr.couiColorBackgroundElevatedWithCard)) } private fun clearDataList() { allFiles.clear() imageFiles.clear() videoFiles.clear() audioFiles.clear() docFiles.clear() otherFiles.clear() mSelectArrayByID.clear() } private fun setViewPagerData(data: MutableList<AddFileBean>) { Log.d(TAG, "setViewPagerData") clearDataList() allFiles.addAll(data) val documentExtensionType = Injector.injectFactory<IDocumentExtensionType>() data.forEach { file -> val localType = file.mLocalType if (MimeTypeHelper.isImageType(localType)) { imageFiles.add(file) } else if (MimeTypeHelper.isVideoType(localType)) { videoFiles.add(file) } else if (MimeTypeHelper.isAudioType(localType)) { audioFiles.add(file) } else if ((MimeTypeHelper.isDocType(localType) || MimeTypeHelper.isOtherDocType(localType)) && documentExtensionType?.isCategoryDocSupportType(file) == true ) { //isCategoryDocSupportType确保面板上文档分类显示的内容和文管文档分类一致(部分未知格式后缀会识解析TXT类型) docFiles.add(file) } else { otherFiles.add(file) } } updateData(mTabTitles[mPosition]) } private fun updateStatisticsSelectView(data: MutableList<AddFileBean>) { if (data.size <= 0) { Log.d(TAG, "unselect file") resetStatisticsView() return } addFileBtn?.isEnabled = true statisticsSelectTitleView?.apply { visibility = View.VISIBLE text = appContext.resources.getQuantityString( com.filemanager.common.R.plurals.mark_selected_items_new, data.size, data.size ) } statisticsSelectBodyView?.apply { visibility = View.VISIBLE val size: Long = data.sumOf { it.mSize } val totalSize: String = updateSizeFormat(size) text = appContext.resources.getString(com.filemanager.common.R.string.selected_size, totalSize) } statisticsArrowUpView?.apply { visibility = View.VISIBLE } statisticsRootView?.apply { isClickable = true } } @SuppressLint("DefaultLocale") fun updateSizeFormat(size: Long): String { return if (size < NUM) { size.toString() + "B" } else if (size < NUM * NUM) { String.format("%.1f", (size / DECIMAL_NUM)) + " KB" } else if (size < NUM * NUM * NUM) { String.format("%.1f", (size / NUM / DECIMAL_NUM)) + " MB" } else { String.format("%.1f", (size / NUM / NUM / DECIMAL_NUM)) + " GB" } } private fun updateData(fragmentType: Int) { val fragment = getCurrentFragment() fragment?.mFragmentType = fragmentType when (fragmentType) { Constants.TAB_ALL -> fragment?.setData(allFiles) Constants.TAB_IMAGE -> fragment?.setData(imageFiles) Constants.TAB_VIDEO -> fragment?.setData(videoFiles) Constants.TAB_AUDIO -> fragment?.setData(audioFiles) Constants.TAB_DOCUMENT -> fragment?.setData(docFiles) Constants.TAB_OTHER -> fragment?.setData(otherFiles) } fragment?.setSelectedData(mSelectArrayByID) Log.d( TAG, "allFiles=${allFiles.size}, imageFiles=${imageFiles.size}, videoFiles=${videoFiles.size}, " + "audioFiles=${audioFiles.size}, docFiles=${docFiles.size}, otherFiles=${otherFiles.size}" ) } override fun onTabSelected(tab: COUITab?) { Log.d(TAG, "onTabSelected tab.postion=${tab?.position}") tab?.let { mPosition = it.position if (loadingController?.isShowing() != true) { updateData(mTabTitles[mPosition]) } } } override fun onTabUnselected(p0: COUITab?) {} override fun onTabReselected(p0: COUITab?) {} private fun getCurrentFragment(): AddFileListFragment? { return if (mPosition < mPages.size) { mPages[mPosition] } else { null } } inner class ViewPagerFragmentStateAdapter(fragment: Fragment) : BaseFragmentAdapter(fragment) { override fun getItemCount(): Int { return mTabTitle.size } override fun createFragment(position: Int): Fragment { return mPages[position] } override fun getPageTitle(position: Int): CharSequence { return mTabTitle[position] } } override fun onAgreeResult(agree: Boolean, noLongerRemind: Boolean) { loadData() } } interface AddFileDialogInterface { fun dismissAddFileDialog() fun replaceSelectedPanelFragment(selectData: MutableList<AddFileBean>) }这是对应的kotlin代码,怎么处理
07-29
/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.android.settings.datausage; import android.app.Application; import android.app.settings.SettingsEnums; import android.content.Context; import android.os.Bundle; import android.telephony.SubscriptionManager; import android.widget.Switch; import android.util.Log; import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.applications.AppStateBaseBridge.Callback; import com.android.settings.datausage.DataSaverBackend.Listener; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.SwitchBar; import com.android.settings.widget.SwitchBar.OnSwitchChangeListener; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState.AppEntry; import com.android.settingslib.applications.ApplicationsState.Callbacks; import com.android.settingslib.applications.ApplicationsState.Session; import com.android.settingslib.search.SearchIndexable; import java.util.ArrayList; @SearchIndexable public class DataSaverSummary extends SettingsPreferenceFragment implements OnSwitchChangeListener, Listener, Callback, Callbacks { private static final String KEY_UNRESTRICTED_ACCESS = "unrestricted_access"; private SwitchBar mSwitchBar; private DataSaverBackend mDataSaverBackend; private Preference mUnrestrictedAccess; private ApplicationsState mApplicationsState; private AppStateDataUsageBridge mDataUsageBridge; private Session mSession; // Flag used to avoid infinite loop due if user switch it on/off too quicky. private boolean mSwitching; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); addPreferencesFromResource(R.xml.data_saver); // addPreferencesFromResource.setVisibility(); mUnrestrictedAccess = findPreference(KEY_UNRESTRICTED_ACCESS); mApplicationsState = ApplicationsState.getInstance( (Application) getContext().getApplicationContext()); mDataSaverBackend = new DataSaverBackend(getContext()); mDataUsageBridge = new AppStateDataUsageBridge(mApplicationsState, this, mDataSaverBackend); mSession = mApplicationsState.newSession(this, getSettingsLifecycle()); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mSwitchBar = ((SettingsActivity) getActivity()).getSwitchBar(); mSwitchBar.setSwitchBarText( R.string.data_saver_switch_title, R.string.data_saver_switch_title); mSwitchBar.show(); mSwitchBar.addOnSwitchChangeListener(this); } @Override public void onResume() { super.onResume(); mDataSaverBackend.refreshWhitelist(); mDataSaverBackend.refreshBlacklist(); mDataSaverBackend.addListener(this); mDataUsageBridge.resume(); } @Override public void onPause() { super.onPause(); mDataSaverBackend.remListener(this); mDataUsageBridge.pause(); } @Override public void onSwitchChanged(Switch switchView, boolean isChecked) { synchronized (this) { if (mSwitching) { return; } mSwitching = true; mDataSaverBackend.setDataSaverEnabled(isChecked); } } @Override public int getMetricsCategory() { return SettingsEnums.DATA_SAVER_SUMMARY; } @Override public int getHelpResource() { return R.string.help_url_data_saver; } @Override public void onDataSaverChanged(boolean isDataSaving) { synchronized (this) { mSwitchBar.setChecked(isDataSaving); mSwitching = false; } } @Override public void onWhitelistStatusChanged(int uid, boolean isWhitelisted) { } @Override public void onBlacklistStatusChanged(int uid, boolean isBlacklisted) { } @Override public void onExtraInfoUpdated() { if (!isAdded()) { return; } int count = 0; final ArrayList<AppEntry> allApps = mSession.getAllApps(); final int N = allApps.size(); for (int i = 0; i < N; i++) { final AppEntry entry = allApps.get(i); if (!ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(entry)) { continue; } if (entry.extraInfo != null && ((AppStateDataUsageBridge.DataUsageState) entry.extraInfo).isDataSaverWhitelisted) { count++; } } mUnrestrictedAccess.setSummary(getResources().getQuantityString( R.plurals.data_saver_unrestricted_summary, count, count)); } @Override public void onRunningStateChanged(boolean running) { } @Override public void onPackageListChanged() { } @Override public void onRebuildComplete(ArrayList<AppEntry> apps) { } @Override public void onPackageIconChanged() { } @Override public void onPackageSizeChanged(String packageName) { } @Override public void onAllSizesComputed() { } @Override public void onLauncherInfoChanged() { } @Override public void onLoadEntriesCompleted() { } public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider(R.xml.data_saver) { @Override protected boolean isPageSearchEnabled(Context context) { return DataUsageUtils.hasMobileData(context) && DataUsageUtils.getDefaultSubscriptionId(context) != SubscriptionManager.INVALID_SUBSCRIPTION_ID; } }; } 如何隐藏掉addPreferencesFromResource(R.xml.data_saver);data_saver这个视图
最新发布
08-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值