fix: 首次提交
This commit is contained in:
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.settingslib.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settingslib.widget.entityheader.R;
|
||||
|
||||
/**
|
||||
* This class is used to initialize view which was inflated
|
||||
* from {@link R.xml.app_entities_header.xml}.
|
||||
*
|
||||
* <p>How to use AppEntitiesHeaderController?
|
||||
*
|
||||
* <p>1. Add a {@link LayoutPreference} in layout XML file.
|
||||
* <pre>
|
||||
* <com.android.settingslib.widget.LayoutPreference
|
||||
* android:key="app_entities_header"
|
||||
* android:layout="@layout/app_entities_header"/>
|
||||
* </pre>
|
||||
*
|
||||
* <p>2. Use AppEntitiesHeaderController to call below methods, then you can initialize
|
||||
* view of <code>app_entities_header</code>.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* View headerView = ((LayoutPreference) screen.findPreference("app_entities_header"))
|
||||
* .findViewById(R.id.app_entities_header);
|
||||
*
|
||||
* final AppEntityInfo appEntityInfo = new AppEntityInfo.Builder()
|
||||
* .setIcon(icon)
|
||||
* .setTitle(title)
|
||||
* .setSummary(summary)
|
||||
* .setOnClickListener(view -> doSomething())
|
||||
* .build();
|
||||
*
|
||||
* AppEntitiesHeaderController.newInstance(context, headerView)
|
||||
* .setHeaderTitleRes(R.string.xxxxx)
|
||||
* .setHeaderDetailsRes(R.string.xxxxx)
|
||||
* .setHeaderDetailsClickListener(onClickListener)
|
||||
* .setAppEntity(0, appEntityInfo)
|
||||
* .setAppEntity(1, appEntityInfo)
|
||||
* .setAppEntity(2, appEntityInfo)
|
||||
* .apply();
|
||||
* </pre>
|
||||
*/
|
||||
public class AppEntitiesHeaderController {
|
||||
|
||||
private static final String TAG = "AppEntitiesHeaderCtl";
|
||||
|
||||
@VisibleForTesting
|
||||
public static final int MAXIMUM_APPS = 3;
|
||||
|
||||
private final Context mContext;
|
||||
private final TextView mHeaderTitleView;
|
||||
private final TextView mHeaderEmptyView;
|
||||
private final Button mHeaderDetailsView;
|
||||
|
||||
private final AppEntityInfo[] mAppEntityInfos;
|
||||
private final View mAppViewsContainer;
|
||||
private final View[] mAppEntityViews;
|
||||
private final ImageView[] mAppIconViews;
|
||||
private final TextView[] mAppTitleViews;
|
||||
private final TextView[] mAppSummaryViews;
|
||||
|
||||
private int mHeaderTitleRes;
|
||||
private int mHeaderDetailsRes;
|
||||
private int mHeaderEmptyRes;
|
||||
private CharSequence mHeaderDetails;
|
||||
private View.OnClickListener mDetailsOnClickListener;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the controller.
|
||||
*
|
||||
* @param context the Context the view is running in
|
||||
* @param appEntitiesHeaderView view was inflated from <code>app_entities_header</code>
|
||||
*/
|
||||
public static AppEntitiesHeaderController newInstance(@NonNull Context context,
|
||||
@NonNull View appEntitiesHeaderView) {
|
||||
return new AppEntitiesHeaderController(context, appEntitiesHeaderView);
|
||||
}
|
||||
|
||||
private AppEntitiesHeaderController(Context context, View appEntitiesHeaderView) {
|
||||
mContext = context;
|
||||
mHeaderTitleView = appEntitiesHeaderView.findViewById(R.id.header_title);
|
||||
mHeaderDetailsView = appEntitiesHeaderView.findViewById(R.id.header_details);
|
||||
mHeaderEmptyView = appEntitiesHeaderView.findViewById(R.id.empty_view);
|
||||
mAppViewsContainer = appEntitiesHeaderView.findViewById(R.id.app_views_container);
|
||||
|
||||
mAppEntityInfos = new AppEntityInfo[MAXIMUM_APPS];
|
||||
mAppIconViews = new ImageView[MAXIMUM_APPS];
|
||||
mAppTitleViews = new TextView[MAXIMUM_APPS];
|
||||
mAppSummaryViews = new TextView[MAXIMUM_APPS];
|
||||
|
||||
mAppEntityViews = new View[]{
|
||||
appEntitiesHeaderView.findViewById(R.id.app1_view),
|
||||
appEntitiesHeaderView.findViewById(R.id.app2_view),
|
||||
appEntitiesHeaderView.findViewById(R.id.app3_view)
|
||||
};
|
||||
|
||||
// Initialize view in advance, so we won't take too much time to do it when controller is
|
||||
// binding view.
|
||||
for (int index = 0; index < MAXIMUM_APPS; index++) {
|
||||
final View appView = mAppEntityViews[index];
|
||||
mAppIconViews[index] = (ImageView) appView.findViewById(R.id.app_icon);
|
||||
mAppTitleViews[index] = (TextView) appView.findViewById(R.id.app_title);
|
||||
mAppSummaryViews[index] = (TextView) appView.findViewById(R.id.app_summary);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text resource for app entities header title.
|
||||
*/
|
||||
public AppEntitiesHeaderController setHeaderTitleRes(@StringRes int titleRes) {
|
||||
mHeaderTitleRes = titleRes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text resource for app entities header details.
|
||||
*/
|
||||
public AppEntitiesHeaderController setHeaderDetailsRes(@StringRes int detailsRes) {
|
||||
mHeaderDetailsRes = detailsRes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text for app entities header details.
|
||||
*/
|
||||
public AppEntitiesHeaderController setHeaderDetails(CharSequence detailsText) {
|
||||
mHeaderDetails = detailsText;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be invoked when header details view is clicked.
|
||||
*/
|
||||
public AppEntitiesHeaderController setHeaderDetailsClickListener(
|
||||
@Nullable View.OnClickListener clickListener) {
|
||||
mDetailsOnClickListener = clickListener;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the string resource id for the empty text.
|
||||
*/
|
||||
public AppEntitiesHeaderController setHeaderEmptyRes(@StringRes int emptyRes) {
|
||||
mHeaderEmptyRes = emptyRes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an app entity at a specified position view.
|
||||
*
|
||||
* @param index the index at which the specified view is to be inserted
|
||||
* @param appEntityInfo the information of an app entity
|
||||
* @return this {@code AppEntitiesHeaderController} object
|
||||
*/
|
||||
public AppEntitiesHeaderController setAppEntity(int index,
|
||||
@NonNull AppEntityInfo appEntityInfo) {
|
||||
mAppEntityInfos[index] = appEntityInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an app entity at a specified position view.
|
||||
*
|
||||
* @param index the index at which the specified view is to be removed
|
||||
* @return this {@code AppEntitiesHeaderController} object
|
||||
*/
|
||||
public AppEntitiesHeaderController removeAppEntity(int index) {
|
||||
mAppEntityInfos[index] = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all app entities in app entities header.
|
||||
*
|
||||
* @return this {@code AppEntitiesHeaderController} object
|
||||
*/
|
||||
public AppEntitiesHeaderController clearAllAppEntities() {
|
||||
for (int index = 0; index < MAXIMUM_APPS; index++) {
|
||||
removeAppEntity(index);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Done mutating app entities header, rebinds everything.
|
||||
*/
|
||||
public void apply() {
|
||||
bindHeaderTitleView();
|
||||
|
||||
if (isAppEntityInfosEmpty()) {
|
||||
setEmptyViewVisible(true);
|
||||
return;
|
||||
}
|
||||
setEmptyViewVisible(false);
|
||||
bindHeaderDetailsView();
|
||||
|
||||
// Rebind all apps view
|
||||
for (int index = 0; index < MAXIMUM_APPS; index++) {
|
||||
bindAppEntityView(index);
|
||||
}
|
||||
}
|
||||
|
||||
private void bindHeaderTitleView() {
|
||||
CharSequence titleText = "";
|
||||
try {
|
||||
titleText = mContext.getText(mHeaderTitleRes);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
Log.e(TAG, "Resource of header title can't not be found!", e);
|
||||
}
|
||||
mHeaderTitleView.setText(titleText);
|
||||
mHeaderTitleView.setVisibility(
|
||||
TextUtils.isEmpty(titleText) ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
private void bindHeaderDetailsView() {
|
||||
CharSequence detailsText = mHeaderDetails;
|
||||
if (TextUtils.isEmpty(detailsText)) {
|
||||
try {
|
||||
detailsText = mContext.getText(mHeaderDetailsRes);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
Log.e(TAG, "Resource of header details can't not be found!", e);
|
||||
}
|
||||
}
|
||||
mHeaderDetailsView.setText(detailsText);
|
||||
mHeaderDetailsView.setVisibility(
|
||||
TextUtils.isEmpty(detailsText) ? View.GONE : View.VISIBLE);
|
||||
mHeaderDetailsView.setOnClickListener(mDetailsOnClickListener);
|
||||
}
|
||||
|
||||
private void bindAppEntityView(int index) {
|
||||
final AppEntityInfo appEntityInfo = mAppEntityInfos[index];
|
||||
mAppEntityViews[index].setVisibility(appEntityInfo != null ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (appEntityInfo != null) {
|
||||
mAppEntityViews[index].setOnClickListener(appEntityInfo.getClickListener());
|
||||
|
||||
mAppIconViews[index].setImageDrawable(appEntityInfo.getIcon());
|
||||
|
||||
final CharSequence title = appEntityInfo.getTitle();
|
||||
mAppTitleViews[index].setVisibility(
|
||||
TextUtils.isEmpty(title) ? View.INVISIBLE : View.VISIBLE);
|
||||
mAppTitleViews[index].setText(title);
|
||||
|
||||
final CharSequence summary = appEntityInfo.getSummary();
|
||||
mAppSummaryViews[index].setVisibility(
|
||||
TextUtils.isEmpty(summary) ? View.INVISIBLE : View.VISIBLE);
|
||||
mAppSummaryViews[index].setText(summary);
|
||||
}
|
||||
}
|
||||
|
||||
private void setEmptyViewVisible(boolean visible) {
|
||||
if (mHeaderEmptyRes != 0) {
|
||||
mHeaderEmptyView.setText(mHeaderEmptyRes);
|
||||
}
|
||||
mHeaderEmptyView.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
mHeaderDetailsView.setVisibility(visible ? View.GONE : View.VISIBLE);
|
||||
mAppViewsContainer.setVisibility(visible ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
private boolean isAppEntityInfosEmpty() {
|
||||
for (AppEntityInfo info : mAppEntityInfos) {
|
||||
if (info != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.settingslib.widget;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.settingslib.widget.entityheader.R;
|
||||
|
||||
/**
|
||||
* AppEntityInfo is responsible for storing app information shown in {@link R.xml.app_view.xml}.
|
||||
*/
|
||||
public class AppEntityInfo {
|
||||
|
||||
private final Drawable mIcon;
|
||||
private final CharSequence mTitle;
|
||||
private final CharSequence mSummary;
|
||||
private final View.OnClickListener mClickListener;
|
||||
|
||||
/**
|
||||
* Gets the drawable for the icon of app entity.
|
||||
*
|
||||
* @return the drawable for the icon of app entity.
|
||||
*/
|
||||
public Drawable getIcon() {
|
||||
return mIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text for the title of app enitity.
|
||||
*
|
||||
* @return the text for the title of app enitity.
|
||||
*/
|
||||
public CharSequence getTitle() {
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text for the summary of app enitity.
|
||||
*
|
||||
* @return the text for the summary of app enitity.
|
||||
*/
|
||||
public CharSequence getSummary() {
|
||||
return mSummary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the click listener for the app entity view.
|
||||
*
|
||||
* @return click listener for the app entity view.
|
||||
*/
|
||||
public View.OnClickListener getClickListener() {
|
||||
return mClickListener;
|
||||
}
|
||||
|
||||
private AppEntityInfo(Builder builder) {
|
||||
mIcon = builder.mIcon;
|
||||
mTitle = builder.mTitle;
|
||||
mSummary = builder.mSummary;
|
||||
mClickListener = builder.mClickListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder class for {@link AppEntityInfo}
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private Drawable mIcon;
|
||||
private CharSequence mTitle;
|
||||
private CharSequence mSummary;
|
||||
private View.OnClickListener mClickListener;
|
||||
|
||||
/**
|
||||
* Creates an instance of a {@link AppEntityInfo} based on the current builder settings.
|
||||
*
|
||||
* @return The {@link AppEntityInfo}.
|
||||
*/
|
||||
public AppEntityInfo build() {
|
||||
return new AppEntityInfo(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the drawable for the icon.
|
||||
*/
|
||||
public Builder setIcon(@NonNull Drawable icon) {
|
||||
mIcon = icon;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text for the title.
|
||||
*/
|
||||
public Builder setTitle(@Nullable CharSequence title) {
|
||||
mTitle = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text for the summary.
|
||||
*/
|
||||
public Builder setSummary(@Nullable CharSequence summary) {
|
||||
mSummary = summary;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the click listener for app entity view.
|
||||
*/
|
||||
public Builder setOnClickListener(@Nullable View.OnClickListener clickListener) {
|
||||
mClickListener = clickListener;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user