Skip to content

Commit a8bdc46

Browse files
tony-makAndroid (Google) Code Review
authored andcommitted
Merge "Refactor app restriction fragment" into ub-testdpc-nyc
2 parents 6fb500f + 7f40f24 commit a8bdc46

22 files changed

+1641
-1072
lines changed

app/build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ android {
9898
}
9999

100100
dependencies {
101-
compile "com.android.support:support-v4:22.0.0"
102-
compile "com.android.support:support-v13:22.0.0"
101+
compile 'com.android.support:appcompat-v7:24.+'
102+
compile 'com.android.support:recyclerview-v7:24.+'
103+
compile "com.android.support:support-v13:24.+"
103104
compile(name:'setup-wizard-lib-platform-release', ext:'aar')
104105
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright (C) 2016 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.afwsamples.testdpc.common;
18+
19+
import android.content.Context;
20+
import android.view.LayoutInflater;
21+
import android.view.View;
22+
import android.view.ViewGroup;
23+
import android.view.ViewParent;
24+
import android.widget.ArrayAdapter;
25+
import android.widget.TextView;
26+
27+
import com.afwsamples.testdpc.R;
28+
29+
import java.util.Collections;
30+
import java.util.Comparator;
31+
import java.util.List;
32+
33+
/**
34+
* List of rows with edit and delete button.
35+
*/
36+
public abstract class EditDeleteArrayAdapter<T> extends ArrayAdapter<T>
37+
implements View.OnClickListener {
38+
39+
private List<T> mEntries;
40+
private OnEditButtonClickListener mOnEditButtonClickListener;
41+
private OnDeleteButtonClickListener mOnDeleteButtonClickListener;
42+
43+
public EditDeleteArrayAdapter(Context context, List<T> entries,
44+
OnEditButtonClickListener onEditButtonClickListener,
45+
OnDeleteButtonClickListener onDeleteButtonClickListener) {
46+
super(context, 0, entries);
47+
mEntries = entries;
48+
mOnEditButtonClickListener = onEditButtonClickListener;
49+
mOnDeleteButtonClickListener = onDeleteButtonClickListener;
50+
}
51+
52+
@Override
53+
public View getView(final int position, View convertView, ViewGroup parent) {
54+
RowViewHolder<T> viewHolder;
55+
if (convertView == null) {
56+
convertView = LayoutInflater.from(getContext()).inflate(
57+
R.layout.edit_delete_row, parent, false);
58+
convertView.findViewById(R.id.edit_row).setOnClickListener(this);
59+
convertView.findViewById(R.id.delete_row).setOnClickListener(this);
60+
61+
viewHolder = new RowViewHolder<>();
62+
convertView.setTag(viewHolder);
63+
viewHolder.restrictionKeyText = (TextView) convertView.findViewById(
64+
R.id.restriction_key);
65+
} else {
66+
viewHolder = (RowViewHolder) convertView.getTag();
67+
}
68+
viewHolder.entry = getItem(position);
69+
viewHolder.restrictionKeyText.setText(getDisplayName(viewHolder.entry));
70+
viewHolder.entryPosition = position;
71+
return convertView;
72+
}
73+
74+
@Override
75+
public void onClick(View view) {
76+
ViewParent parentView = view.getParent();
77+
if (!(parentView instanceof View) || ((View) parentView).getTag() == null) {
78+
return;
79+
}
80+
final RowViewHolder<T> viewHolder =
81+
(RowViewHolder<T>) ((View) parentView).getTag();
82+
final T entry = viewHolder.entry;
83+
if (view.getId() == R.id.edit_row) {
84+
mOnEditButtonClickListener.onEditButtonClick(entry);
85+
} else if (view.getId() == R.id.delete_row) {
86+
remove(entry);
87+
if (mOnDeleteButtonClickListener != null) {
88+
mOnDeleteButtonClickListener.onDeleteButtonClick(entry);
89+
}
90+
}
91+
}
92+
93+
@Override
94+
public void notifyDataSetChanged() {
95+
if (mEntries != null) {
96+
Collections.sort(mEntries, new Comparator<T>() {
97+
@Override
98+
public int compare(T entry1, T entry2) {
99+
return getDisplayName(entry1).compareTo(getDisplayName(entry2));
100+
}
101+
});
102+
}
103+
super.notifyDataSetChanged();
104+
}
105+
106+
public void set(int index, T item) {
107+
mEntries.set(index, item);
108+
notifyDataSetChanged();
109+
}
110+
111+
protected abstract String getDisplayName(T entry);
112+
113+
private static class RowViewHolder<T> {
114+
T entry;
115+
TextView restrictionKeyText;
116+
int entryPosition;
117+
}
118+
119+
public interface OnEditButtonClickListener<T> {
120+
void onEditButtonClick(T entry);
121+
}
122+
123+
public interface OnDeleteButtonClickListener<T> {
124+
void onDeleteButtonClick(T entry);
125+
}
126+
}

app/src/main/java/com/afwsamples/testdpc/common/ManageAppFragment.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import android.widget.AdapterView;
2727
import android.widget.ListView;
2828
import android.widget.Spinner;
29+
import android.widget.TextView;
2930

3031
import com.afwsamples.testdpc.R;
3132

@@ -37,10 +38,11 @@
3738
* This fragment shows a spinner of all allowed apps and a list of properties associated with the
3839
* currently selected application.
3940
*/
40-
public abstract class ManageAppFragment extends Fragment {
41+
public abstract class ManageAppFragment extends Fragment implements View.OnClickListener {
4142

4243
protected PackageManager mPackageManager;
4344
protected Spinner mManagedAppsSpinner;
45+
protected TextView mHeaderView;
4446
protected ListView mAppListView;
4547

4648
@Override
@@ -65,6 +67,7 @@ public View onCreateView(LayoutInflater layoutInflater, ViewGroup container,
6567
new ApplicationInfo.DisplayNameComparator(mPackageManager));
6668
AppInfoSpinnerAdapter appInfoSpinnerAdapter = new AppInfoSpinnerAdapter(getActivity(),
6769
R.layout.app_row, R.id.pkg_name, managedAppList);
70+
mHeaderView = (TextView) view.findViewById(R.id.header_text);
6871
mManagedAppsSpinner = (Spinner) view.findViewById(R.id.managed_apps_list);
6972
mManagedAppsSpinner.setAdapter(appInfoSpinnerAdapter);
7073
mManagedAppsSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@@ -79,6 +82,10 @@ public void onNothingSelected(AdapterView<?> parent) {
7982
}
8083
});
8184
mAppListView = (ListView) view.findViewById(R.id.app_list_view);
85+
view.findViewById(R.id.save_app).setOnClickListener(this);
86+
view.findViewById(R.id.reset_app).setOnClickListener(this);
87+
view.findViewById(R.id.add_new_row).setOnClickListener(this);
88+
view.findViewById(R.id.load_default_button).setOnClickListener(this);
8289
loadData(((ApplicationInfo) mManagedAppsSpinner.getSelectedItem()).packageName);
8390
return view;
8491
}
@@ -101,4 +108,25 @@ private List<ApplicationInfo> getInstalledLaunchableApps() {
101108
*/
102109
protected abstract void loadData(String pkgName);
103110

111+
@Override
112+
public void onClick(View view) {
113+
switch (view.getId()) {
114+
case R.id.reset_app:
115+
resetConfig();
116+
break;
117+
case R.id.save_app:
118+
saveConfig();
119+
break;
120+
case R.id.add_new_row:
121+
addNewRow();
122+
break;
123+
case R.id.load_default_button:
124+
loadDefault();
125+
}
126+
}
127+
128+
protected abstract void resetConfig();
129+
protected abstract void saveConfig();
130+
protected abstract void addNewRow();
131+
protected abstract void loadDefault();
104132
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright (C) 2016 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.afwsamples.testdpc.common;
18+
19+
import android.support.v7.widget.RecyclerView;
20+
import android.text.Editable;
21+
import android.text.TextWatcher;
22+
import android.view.LayoutInflater;
23+
import android.view.View;
24+
import android.view.ViewGroup;
25+
import android.widget.EditText;
26+
import android.widget.ImageView;
27+
28+
import com.afwsamples.testdpc.R;
29+
30+
import java.util.ArrayList;
31+
import java.util.List;
32+
33+
public class StringArrayTypeInputAdapter extends
34+
RecyclerView.Adapter<StringArrayTypeInputAdapter.ViewHolder> {
35+
private List<String> mStringList;
36+
37+
public StringArrayTypeInputAdapter() {
38+
mStringList = new ArrayList<>();
39+
}
40+
41+
@Override
42+
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
43+
View view = LayoutInflater.from(parent.getContext())
44+
.inflate(R.layout.string_array_row, parent, false);
45+
return new ViewHolder(view);
46+
}
47+
48+
@Override
49+
public void onBindViewHolder(final ViewHolder holder, final int position) {
50+
holder.stringValue.setText(mStringList.get(position));
51+
if (holder.textWatcher != null) {
52+
holder.stringValue.removeTextChangedListener(holder.textWatcher);
53+
}
54+
holder.textWatcher = createEditTextTextWatcher(holder);
55+
holder.stringValue.addTextChangedListener(holder.textWatcher);
56+
holder.delete.setOnClickListener(new View.OnClickListener() {
57+
@Override
58+
public void onClick(View view) {
59+
int adapterPosition = holder.getAdapterPosition();
60+
// make sure the view is not removed yet.
61+
if (adapterPosition != -1) {
62+
mStringList.remove(adapterPosition);
63+
notifyItemRemoved(adapterPosition);
64+
}
65+
}
66+
});
67+
}
68+
69+
@Override
70+
public int getItemCount() {
71+
return mStringList.size();
72+
}
73+
74+
public List<String> getStringList() {
75+
return mStringList;
76+
}
77+
78+
public void setStringList(List<String> stringList) {
79+
mStringList = stringList;
80+
notifyDataSetChanged();
81+
}
82+
83+
public class ViewHolder extends RecyclerView.ViewHolder {
84+
public EditText stringValue;
85+
public ImageView delete;
86+
public TextWatcher textWatcher;
87+
88+
public ViewHolder(View view) {
89+
super(view);
90+
stringValue = (EditText) view.findViewById(R.id.string_input);
91+
delete = (ImageView) view.findViewById(R.id.delete_row);
92+
}
93+
}
94+
95+
private TextWatcher createEditTextTextWatcher(final ViewHolder viewHolder) {
96+
return new TextWatcher() {
97+
@Override
98+
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
99+
100+
@Override
101+
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
102+
103+
@Override
104+
public void afterTextChanged(Editable editable) {
105+
mStringList.set(viewHolder.getAdapterPosition(), editable.toString());
106+
}
107+
};
108+
}
109+
}

0 commit comments

Comments
 (0)