Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2015 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.internal.widget;
     18 
     19 import android.annotation.Nullable;
     20 import android.content.Context;
     21 import android.text.BoringLayout;
     22 import android.text.Layout;
     23 import android.text.StaticLayout;
     24 import android.text.TextUtils;
     25 import android.util.AttributeSet;
     26 import android.view.RemotableViewMethod;
     27 import android.widget.RemoteViews;
     28 import android.widget.TextView;
     29 
     30 import com.android.internal.R;
     31 
     32 /**
     33  * A TextView that can float around an image on the end.
     34  *
     35  * @hide
     36  */
     37 @RemoteViews.RemoteView
     38 public class ImageFloatingTextView extends TextView {
     39 
     40     /** Number of lines from the top to indent */
     41     private int mIndentLines;
     42 
     43     public ImageFloatingTextView(Context context) {
     44         this(context, null);
     45     }
     46 
     47     public ImageFloatingTextView(Context context, @Nullable AttributeSet attrs) {
     48         this(context, attrs, 0);
     49     }
     50 
     51     public ImageFloatingTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
     52         this(context, attrs, defStyleAttr, 0);
     53     }
     54 
     55     public ImageFloatingTextView(Context context, AttributeSet attrs, int defStyleAttr,
     56             int defStyleRes) {
     57         super(context, attrs, defStyleAttr, defStyleRes);
     58     }
     59 
     60     @Override
     61     protected Layout makeSingleLayout(int wantWidth, BoringLayout.Metrics boring, int ellipsisWidth,
     62             Layout.Alignment alignment, boolean shouldEllipsize,
     63             TextUtils.TruncateAt effectiveEllipsize, boolean useSaved) {
     64         CharSequence text = getText() == null ? "" : getText();
     65         StaticLayout.Builder builder = StaticLayout.Builder.obtain(text, 0, text.length(),
     66                 getPaint(), wantWidth)
     67                 .setAlignment(alignment)
     68                 .setTextDirection(getTextDirectionHeuristic())
     69                 .setLineSpacing(getLineSpacingExtra(), getLineSpacingMultiplier())
     70                 .setIncludePad(getIncludeFontPadding())
     71                 .setEllipsize(shouldEllipsize ? effectiveEllipsize : null)
     72                 .setEllipsizedWidth(ellipsisWidth)
     73                 .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
     74                 .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
     75         // we set the endmargin on the requested number of lines.
     76         int endMargin = getContext().getResources().getDimensionPixelSize(
     77                 R.dimen.notification_content_picture_margin);
     78         int[] margins = null;
     79         if (mIndentLines > 0) {
     80             margins = new int[mIndentLines + 1];
     81             for (int i = 0; i < mIndentLines; i++) {
     82                 margins[i] = endMargin;
     83             }
     84         }
     85         if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
     86             builder.setIndents(margins, null);
     87         } else {
     88             builder.setIndents(null, margins);
     89         }
     90 
     91         return builder.build();
     92     }
     93 
     94     @RemotableViewMethod
     95     public void setHasImage(boolean hasImage) {
     96         setNumIndentLines(hasImage ? 2 : 0);
     97     }
     98 
     99     /**
    100      * @param lines the number of lines at the top that should be indented by indentEnd
    101      * @return whether a change was made
    102      */
    103     public boolean setNumIndentLines(int lines) {
    104         if (mIndentLines != lines) {
    105             mIndentLines = lines;
    106             // Invalidate layout.
    107             setHint(getHint());
    108             return true;
    109         }
    110         return false;
    111     }
    112 }
    113