1 /* 2 * Copyright (C) 2022 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.android.settings.accessibility; 18 19 import android.content.Context; 20 import android.util.AttributeSet; 21 import android.view.View; 22 import android.widget.FrameLayout; 23 import android.widget.LinearLayout; 24 25 import androidx.preference.Preference; 26 import androidx.preference.PreferenceViewHolder; 27 import androidx.viewpager.widget.ViewPager; 28 29 import com.android.internal.annotations.VisibleForTesting; 30 import com.android.internal.util.Preconditions; 31 import com.android.settings.R; 32 import com.android.settings.display.PreviewPagerAdapter; 33 import com.android.settings.widget.DotsPageIndicator; 34 35 /** 36 * A {@link Preference} that could show the preview related to the text and reading options. 37 */ 38 public class TextReadingPreviewPreference extends Preference { 39 private int mCurrentItem; 40 private int mLastLayerIndex; 41 private PreviewPagerAdapter mPreviewAdapter; 42 43 private int mLayoutMinHorizontalPadding = 0; 44 private int mBackgroundMinHorizontalPadding = 0; 45 46 private final ViewPager.OnPageChangeListener mPageChangeListener = 47 new ViewPager.OnPageChangeListener() { 48 @Override 49 public void onPageScrolled(int i, float v, int i1) { 50 // Do nothing 51 } 52 53 @Override 54 public void onPageSelected(int i) { 55 mCurrentItem = i; 56 } 57 58 @Override 59 public void onPageScrollStateChanged(int i) { 60 // Do nothing 61 } 62 }; 63 TextReadingPreviewPreference(Context context)64 TextReadingPreviewPreference(Context context) { 65 super(context); 66 init(); 67 } 68 TextReadingPreviewPreference(Context context, AttributeSet attrs)69 public TextReadingPreviewPreference(Context context, AttributeSet attrs) { 70 super(context, attrs); 71 init(); 72 } 73 TextReadingPreviewPreference(Context context, AttributeSet attrs, int defStyleAttr)74 TextReadingPreviewPreference(Context context, AttributeSet attrs, int defStyleAttr) { 75 super(context, attrs, defStyleAttr); 76 init(); 77 } 78 TextReadingPreviewPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)79 TextReadingPreviewPreference(Context context, AttributeSet attrs, int defStyleAttr, 80 int defStyleRes) { 81 super(context, attrs, defStyleAttr, defStyleRes); 82 init(); 83 } 84 85 @Override onBindViewHolder(PreferenceViewHolder holder)86 public void onBindViewHolder(PreferenceViewHolder holder) { 87 super.onBindViewHolder(holder); 88 89 FrameLayout previewLayout = (FrameLayout) holder.itemView; 90 LinearLayout backgroundView = previewLayout.findViewById(R.id.preview_background); 91 adjustPaddings(previewLayout, backgroundView); 92 93 final ViewPager viewPager = (ViewPager) holder.findViewById(R.id.preview_pager); 94 viewPager.addOnPageChangeListener(mPageChangeListener); 95 final DotsPageIndicator pageIndicator = 96 (DotsPageIndicator) holder.findViewById(R.id.page_indicator); 97 updateAdapterIfNeeded(viewPager, pageIndicator, mPreviewAdapter); 98 updatePagerAndIndicator(viewPager, pageIndicator); 99 } 100 101 /** 102 * Set the minimum preview layout horizontal inner padding. 103 */ setLayoutMinHorizontalPadding(int layoutMinHorizontalPadding)104 void setLayoutMinHorizontalPadding(int layoutMinHorizontalPadding) { 105 mLayoutMinHorizontalPadding = layoutMinHorizontalPadding; 106 } 107 108 /** 109 * Set the minimum preview background view horizontal inner padding. 110 */ setBackgroundMinHorizontalPadding(int backgroundMinHorizontalPadding)111 void setBackgroundMinHorizontalPadding(int backgroundMinHorizontalPadding) { 112 mBackgroundMinHorizontalPadding = backgroundMinHorizontalPadding; 113 } 114 115 @VisibleForTesting adjustPaddings(FrameLayout previewLayout, LinearLayout backgroundView)116 void adjustPaddings(FrameLayout previewLayout, LinearLayout backgroundView) { 117 previewLayout.setPadding( 118 Math.max(previewLayout.getPaddingStart(), mLayoutMinHorizontalPadding), 119 previewLayout.getPaddingTop(), 120 Math.max(previewLayout.getPaddingEnd(), mLayoutMinHorizontalPadding), 121 previewLayout.getPaddingBottom() 122 ); 123 backgroundView.setPadding( 124 Math.max(backgroundView.getPaddingStart(), mBackgroundMinHorizontalPadding), 125 backgroundView.getPaddingTop(), 126 Math.max(backgroundView.getPaddingEnd(), mBackgroundMinHorizontalPadding), 127 backgroundView.getPaddingBottom() 128 ); 129 } 130 setPreviewAdapter(PreviewPagerAdapter previewAdapter)131 void setPreviewAdapter(PreviewPagerAdapter previewAdapter) { 132 if (previewAdapter != mPreviewAdapter) { 133 mPreviewAdapter = previewAdapter; 134 notifyChanged(); 135 } 136 } 137 setCurrentItem(int currentItem)138 void setCurrentItem(int currentItem) { 139 Preconditions.checkNotNull(mPreviewAdapter, 140 "Preview adapter is null, you should init the preview adapter first"); 141 142 if (currentItem != mCurrentItem) { 143 mCurrentItem = currentItem; 144 notifyChanged(); 145 } 146 } 147 setLastLayerIndex(int lastLayerIndex)148 void setLastLayerIndex(int lastLayerIndex) { 149 mLastLayerIndex = lastLayerIndex; 150 } 151 getCurrentItem()152 int getCurrentItem() { 153 return mCurrentItem; 154 } 155 updateAdapterIfNeeded(ViewPager viewPager, DotsPageIndicator pageIndicator, PreviewPagerAdapter previewAdapter)156 private void updateAdapterIfNeeded(ViewPager viewPager, DotsPageIndicator pageIndicator, 157 PreviewPagerAdapter previewAdapter) { 158 if (viewPager.getAdapter() == previewAdapter) { 159 return; 160 } 161 162 viewPager.setAdapter(previewAdapter); 163 164 if (previewAdapter != null) { 165 pageIndicator.setViewPager(viewPager); 166 } else { 167 mCurrentItem = 0; 168 } 169 } 170 updatePagerAndIndicator(ViewPager viewPager, DotsPageIndicator pageIndicator)171 private void updatePagerAndIndicator(ViewPager viewPager, DotsPageIndicator pageIndicator) { 172 if (viewPager.getAdapter() == null) { 173 return; 174 } 175 176 if (viewPager.getCurrentItem() != mCurrentItem) { 177 viewPager.setCurrentItem(mCurrentItem); 178 } 179 180 pageIndicator.setVisibility( 181 viewPager.getAdapter().getCount() > 1 ? View.VISIBLE : View.GONE); 182 } 183 init()184 private void init() { 185 // set up the minimum horizontal paddings 186 setLayoutMinHorizontalPadding(getContext().getResources().getDimensionPixelSize( 187 R.dimen.text_reading_preview_layout_padding_horizontal_min)); 188 setBackgroundMinHorizontalPadding(getContext().getResources().getDimensionPixelSize( 189 R.dimen.text_reading_preview_background_padding_horizontal_min)); 190 191 setLayoutResource(R.layout.accessibility_text_reading_preview); 192 } 193 notifyPreviewPagerChanged(int pagerIndex)194 void notifyPreviewPagerChanged(int pagerIndex) { 195 Preconditions.checkNotNull(mPreviewAdapter, 196 "Preview adapter is null, you should init the preview adapter first"); 197 198 if (pagerIndex != mLastLayerIndex) { 199 mPreviewAdapter.setPreviewLayer(pagerIndex, mLastLayerIndex, getCurrentItem(), 200 /* animate= */ false); 201 } 202 203 mLastLayerIndex = pagerIndex; 204 } 205 } 206