TermsListAdapter.java revision 409de097fb94e4ecf05fa582140ae01d1c54f49e
1/* 2 * Copyright 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 */ 16package com.android.managedprovisioning.preprovisioning.terms; 17 18import static com.android.internal.util.Preconditions.checkNotNull; 19 20import android.text.Spanned; 21import android.text.method.LinkMovementMethod; 22import android.view.LayoutInflater; 23import android.view.View; 24import android.view.ViewGroup; 25import android.view.accessibility.AccessibilityNodeInfo; 26import android.widget.BaseExpandableListAdapter; 27import android.widget.ImageView; 28import android.widget.TextView; 29 30import com.android.managedprovisioning.R; 31import com.android.managedprovisioning.common.HtmlToSpannedParser; 32 33import java.util.List; 34 35/** 36 * Allows for displaying {@link TermsDocument} objects in an 37 * {@link android.widget.ExpandableListView}. 38 */ 39class TermsListAdapter extends BaseExpandableListAdapter { 40 private final List<TermsDocument> mTermsDocuments; 41 private final LayoutInflater mInflater; 42 private final HtmlToSpannedParser mHtmlToSpannedParser; 43 private final GroupExpandedInfo mGroupExpandedInfo; 44 45 /** 46 * Creates a new instance of the class. 47 */ 48 TermsListAdapter(List<TermsDocument> termsDocuments, LayoutInflater layoutInflater, 49 HtmlToSpannedParser htmlToSpannedParser, GroupExpandedInfo groupExpandedInfo) { 50 mTermsDocuments = checkNotNull(termsDocuments); 51 mInflater = checkNotNull(layoutInflater); 52 mHtmlToSpannedParser = checkNotNull(htmlToSpannedParser); 53 mGroupExpandedInfo = checkNotNull(groupExpandedInfo); 54 } 55 56 @Override 57 public int getGroupCount() { 58 return mTermsDocuments.size(); 59 } 60 61 @Override 62 public int getChildrenCount(int groupPosition) { 63 return 1; // one content piece per header 64 } 65 66 @Override 67 public TermsDocument getGroup(int groupPosition) { 68 return getDisclaimer(groupPosition); 69 } 70 71 @Override 72 public TermsDocument getChild(int groupPosition, int childPosition) { 73 return getDisclaimer(groupPosition); 74 } 75 76 @Override 77 public long getGroupId(int groupPosition) { 78 return groupPosition; 79 } 80 81 @Override 82 public long getChildId(int groupPosition, int childPosition) { 83 return childPosition; 84 } 85 86 @Override 87 public boolean hasStableIds() { 88 return true; 89 } 90 91 // TODO: encapsulate this logic - too much direct view manipulation 92 @Override 93 public View getGroupView(int groupPosition, boolean isExpanded, View convertView, 94 ViewGroup parent) { 95 String heading = getDisclaimer(groupPosition).getHeading(); 96 97 View groupView = convertView != null ? convertView : mInflater.inflate( 98 R.layout.terms_disclaimer_header, parent, false); 99 groupView.setContentDescription( 100 parent.getResources().getString(R.string.section_heading, heading)); 101 groupView.setAccessibilityDelegate(new View.AccessibilityDelegate() { 102 @Override public void onInitializeAccessibilityNodeInfo(View host, 103 AccessibilityNodeInfo info) { 104 super.onInitializeAccessibilityNodeInfo(host, info); 105 info.addAction(new AccessibilityNodeInfo.AccessibilityAction( 106 AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.getId(), 107 parent.getResources().getString( 108 isExpanded ? R.string.collapse : R.string.expand))); 109 } 110 }); 111 112 TextView textView = groupView.findViewById(R.id.header_text); 113 textView.setText(heading); 114 115 ImageView chevron = groupView.findViewById(R.id.chevron); 116 chevron.setRotation(isExpanded ? 90 : -90); // chevron down / up retrospectively 117 groupView.findViewById(R.id.divider).setVisibility( 118 shouldShowGroupDivider(groupPosition) ? View.VISIBLE : View.INVISIBLE); 119 120 return groupView; 121 } 122 123 /** 124 * Helps avoid a double thick divider line: one above header, one from the bottom of prev child 125 */ 126 private boolean shouldShowGroupDivider(int groupPosition) { 127 return mGroupExpandedInfo.isGroupExpanded(groupPosition) 128 && (groupPosition == 0 || !mGroupExpandedInfo.isGroupExpanded(groupPosition - 1)); 129 } 130 131 // TODO: encapsulate this logic - too much direct view manipulation 132 @Override 133 public View getChildView(int groupPosition, int childPosition, boolean isLastChild, 134 View convertView, ViewGroup parent) { 135 View view = convertView != null ? convertView : mInflater.inflate( 136 R.layout.terms_disclaimer_content, parent, false); 137 138 TermsDocument disclaimer = getDisclaimer(groupPosition); 139 TextView textView = view.findViewById(R.id.disclaimer_content); 140 Spanned content = mHtmlToSpannedParser.parseHtml(disclaimer.getContent()); 141 textView.setText(content); 142 textView.setContentDescription( 143 parent.getResources().getString(R.string.section_content, disclaimer.getHeading(), 144 content)); 145 textView.setMovementMethod(LinkMovementMethod.getInstance()); // makes html links clickable 146 147 return view; 148 } 149 150 private TermsDocument getDisclaimer(int index) { 151 return mTermsDocuments.get(index); 152 } 153 154 @Override 155 public boolean isChildSelectable(int groupPosition, int childPosition) { 156 return false; 157 } 158 159 interface GroupExpandedInfo { 160 boolean isGroupExpanded(int groupPosition); 161 } 162}