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