zoukankan      html  css  js  c++  java
  • 自定义编辑框 + 搜索页面无序排列

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:background="@drawable/bg_search" >
     6 
     7     <LinearLayout
     8         android:id="@+id/search_layout"
     9         android:layout_width="match_parent"
    10         android:layout_height="wrap_content"
    11         android:layout_alignParentLeft="true"
    12         android:layout_alignParentTop="true"
    13         android:layout_marginLeft="25dp"
    14         android:layout_marginRight="25dp"
    15         android:layout_marginTop="30dp"
    16         android:orientation="vertical" >
    17 
    18         <com.wxcily.xunbo2.DeletableEditText
    19             android:id="@+id/search_view"
    20             android:layout_width="match_parent"
    21             android:layout_height="wrap_content"
    22             android:background="@drawable/bg_edittext"
    23             android:drawableLeft="@drawable/ic_edittext_search"
    24             android:drawablePadding="6dp"
    25             android:drawableRight="@drawable/ic_edittext_delete"
    26             android:hint="请输入您要搜索的影片..."
    27             android:paddingBottom="7dp"
    28             android:paddingLeft="9dp"
    29             android:paddingRight="8dp"
    30             android:paddingTop="7dp"
    31             android:singleLine="true"
    32             android:textColor="#ffffff"
    33             android:textCursorDrawable="@null"
    34             android:textSize="16dp" />
    35 
    36         <LinearLayout
    37             android:layout_width="wrap_content"
    38             android:layout_height="wrap_content"
    39             android:layout_marginTop="10dp"
    40             android:orientation="horizontal" >
    41 
    42             <Button
    43                 android:id="@+id/search_button"
    44                 android:layout_width="match_parent"
    45                 android:layout_height="33dp"
    46                 android:background="@drawable/bg_button_green"
    47                 android:drawableLeft="@drawable/ic_button_search"
    48                 android:drawablePadding="5dp"
    49                 android:paddingLeft="20dp"
    50                 android:paddingRight="20dp"
    51                 android:text="云搜索"
    52                 android:textColor="#ffffff"
    53                 android:textSize="16dp" />
    54 
    55             <Button
    56                 android:id="@+id/app_button"
    57                 android:layout_width="match_parent"
    58                 android:layout_height="33dp"
    59                 android:layout_marginLeft="10dp"
    60                 android:background="@drawable/bg_button_red"
    61                 android:drawableLeft="@drawable/ic_button_star"
    62                 android:drawablePadding="5dp"
    63                 android:paddingLeft="15dp"
    64                 android:paddingRight="15dp"
    65                 android:text="精品应用"
    66                 android:textColor="#ffffff"
    67                 android:textSize="16dp" />
    68         </LinearLayout>
    69     </LinearLayout>
    70 
    71     <com.wxcily.xunbo2.KeywordsFlow
    72         android:id="@+id/keywordsflow"
    73         android:layout_width="match_parent"
    74         android:layout_height="match_parent"
    75         android:layout_below="@+id/search_layout" />
    76 
    77     <ImageView
    78         android:id="@+id/back_arrow"
    79         android:layout_width="wrap_content"
    80         android:layout_height="wrap_content"
    81         android:layout_alignParentBottom="true"
    82         android:layout_centerHorizontal="true"
    83         android:layout_marginBottom="14dp"
    84         android:src="@drawable/ic_back_arrow" />
    85 
    86 </RelativeLayout>
     1 <!-- bg_button_green.xml -->
     2 <?xml version="1.0" encoding="utf-8"?>
     3 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     5     <item android:state_pressed="true"><shape>
     6             <solid android:color="#24a042" />
     7             <corners android:radius="3dip" />
     8         </shape></item>
     9     <item><shape>
    10             <solid android:color="#4cc05f" />
    11             <corners android:radius="3dip" />
    12         </shape></item>
    13 </selector>
    <!-- bg_button_red.xml -->
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true"><shape>
                <solid android:color="#a34337" />
                <corners android:radius="3dip" />
            </shape></item>
        <item><shape>
                <solid android:color="#cc4238" />
                <corners android:radius="3dip" />
            </shape></item>
    </selector>
      1 import android.content.Context;
      2 import android.graphics.drawable.Drawable;
      3 import android.text.Editable;
      4 import android.text.TextWatcher;
      5 import android.util.AttributeSet;
      6 import android.view.MotionEvent;
      7 import android.view.View;
      8 import android.view.animation.Animation;
      9 import android.view.animation.CycleInterpolator;
     10 import android.view.animation.TranslateAnimation;
     11 import android.widget.EditText;
     12 
     13 // 自定义控件
     14 public class DeletableEditText extends EditText {
     15     private Drawable mRightDrawable;
     16     private boolean isHasFocus;
     17 
     18     public DeletableEditText(Context context) {
     19         super(context);
     20         init();
     21     }
     22 
     23     public DeletableEditText(Context context, AttributeSet attrs) {
     24         super(context, attrs);
     25         init();
     26     }
     27 
     28     public DeletableEditText(Context context, AttributeSet attrs, int defStyle) {
     29         super(context, attrs, defStyle);
     30         init();
     31     }
     32 
     33     private void init() {
     34         // getCompoundDrawables:
     35         // Returns drawables for the left, top, right, and bottom borders.
     36         Drawable[] drawables = this.getCompoundDrawables();
     37 
     38         // 取得right位置的Drawable
     39         // 即我们在布局文件中设置的android:drawableRight
     40         mRightDrawable = drawables[2];
     41 
     42         // 设置焦点变化的监听
     43         this.setOnFocusChangeListener(new FocusChangeListenerImpl());
     44         // 设置EditText文字变化的监听
     45         this.addTextChangedListener(new TextWatcherImpl());
     46         // 初始化时让右边clean图标不可见
     47         setClearDrawableVisible(false);
     48     }
     49 
     50     /**
     51      * 当手指抬起的位置在clean的图标的区域 我们将此视为进行清除操作 getWidth():得到控件的宽度
     52      * event.getX():抬起时的坐标(改坐标是相对于控件本身而言的)
     53      * getTotalPaddingRight():clean的图标左边缘至控件右边缘的距离
     54      * getPaddingRight():clean的图标右边缘至控件右边缘的距离 于是: getWidth() -
     55      * getTotalPaddingRight()表示: 控件左边到clean的图标左边缘的区域 getWidth() -
     56      * getPaddingRight()表示: 控件左边到clean的图标右边缘的区域 所以这两者之间的区域刚好是clean的图标的区域
     57      */
     58     @Override
     59     public boolean onTouchEvent(MotionEvent event) {
     60         switch (event.getAction()) {
     61         case MotionEvent.ACTION_UP:
     62 
     63             boolean isClean = (event.getX() > (getWidth() - getTotalPaddingRight()))
     64                     && (event.getX() < (getWidth() - getPaddingRight()));
     65             if (isClean) {
     66                 setText("");
     67             }
     68             break;
     69 
     70         default:
     71             break;
     72         }
     73         return super.onTouchEvent(event);
     74     }
     75 
     76     private class FocusChangeListenerImpl implements OnFocusChangeListener {
     77         @Override
     78         public void onFocusChange(View v, boolean hasFocus) {
     79             isHasFocus = hasFocus;
     80             if (isHasFocus) {
     81                 boolean isVisible = getText().toString().length() >= 1;
     82                 setClearDrawableVisible(isVisible);
     83             } else {
     84                 setClearDrawableVisible(false);
     85             }
     86         }
     88     }
     89 
     90     // 当输入结束后判断是否显示右边clean的图标
     91     private class TextWatcherImpl implements TextWatcher {
     92         @Override
     93         public void afterTextChanged(Editable s) {
     94             boolean isVisible = getText().toString().length() >= 1;
     95             setClearDrawableVisible(isVisible);
     96         }
     98         @Override
     99         public void beforeTextChanged(CharSequence s, int start, int count,
    100                 int after) {
    101         }
    103         @Override
    104         public void onTextChanged(CharSequence s, int start, int before,
    105                 int count) {
    106         }
    108     }
    109 
    110     // 隐藏或者显示右边clean的图标
    111     protected void setClearDrawableVisible(boolean isVisible) {
    112         Drawable rightDrawable;
    113         if (isVisible) {
    114             rightDrawable = mRightDrawable;
    115         } else {
    116             rightDrawable = null;
    117         }
    118         // 使用代码设置该控件left, top, right, and bottom处的图标
    119         setCompoundDrawables(getCompoundDrawables()[0],
    120                 getCompoundDrawables()[1], rightDrawable,
    121                 getCompoundDrawables()[3]);
    122     }
    123 
    124     // 显示一个动画,以提示用户输入
    125     public void setShakeAnimation() {
    126         this.startAnimation(shakeAnimation(5));
    128     }
    129 
    130     // CycleTimes动画重复的次数
    131     public Animation shakeAnimation(int CycleTimes) {
    132         Animation translateAnimation = new TranslateAnimation(0, 10, 0, 10);
    133         translateAnimation.setInterpolator(new CycleInterpolator(CycleTimes));
    134         translateAnimation.setDuration(1000);
    135         return translateAnimation;
    136     }
    137 }
    import java.util.Random;
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.animation.Animation;
    import android.view.animation.AnimationUtils;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    public class MainActivity extends Activity implements OnClickListener {
        private static final int FEEDKEY_START = 1;
        private ImageView back_arrow;
        private Animation shakeAnim;
        private DeletableEditText searchEdit;
        private KeywordsFlow keywordsFlow;
        private int STATE = 1;
    
        private static String[] keywords = new String[] { "娘要嫁人", "球爱酒吧", "使徒行者",
                "亮剑", "完美搭档", "致青春", "非常完美", "一生一世", "穿越火线", "天龙八部", "匹诺曹", "让子弹飞",
                "穿越火线", "情定三生", "心术", "马向阳下乡记", "人在囧途", " 高达", " 刀剑神域", "泡芙小姐",
                "尖刀出鞘", "甄嬛传", "兵出潼关", "电锯惊魂3D", "古剑奇谭", "同桌的你" };
    
        private Handler handler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                case FEEDKEY_START:
                    keywordsFlow.rubKeywords();
                    feedKeywordsFlow(keywordsFlow, keywords);
                    keywordsFlow.go2Show(KeywordsFlow.ANIMATION_OUT);
                    sendEmptyMessageDelayed(FEEDKEY_START, 5000);
                    break;
                }
            };
        };
    
        private static void feedKeywordsFlow(KeywordsFlow keywordsFlow, String[] arr) {
            Random random = new Random();
            for (int i = 0; i < KeywordsFlow.MAX; i++) {
                int ran = random.nextInt(arr.length);
                String tmp = arr[ran];
                keywordsFlow.feedKeyword(tmp);
            }
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_search);
            shakeAnim = AnimationUtils.loadAnimation(this, R.anim.shake_y);
            initView();
        }
    
        private void initView() {
            keywordsFlow = (KeywordsFlow) findViewById(R.id.keywordsflow);
            keywordsFlow.setDuration(1000l);
            keywordsFlow.setOnItemClickListener(this);
            back_arrow = (ImageView) findViewById(R.id.back_arrow);
            back_arrow.setAnimation(shakeAnim);
            searchEdit = (DeletableEditText) findViewById(R.id.search_view);
            feedKeywordsFlow(keywordsFlow, keywords);
            keywordsFlow.go2Show(KeywordsFlow.ANIMATION_IN);
            handler.sendEmptyMessageDelayed(FEEDKEY_START, 5000);
        }
    
        @Override
        public void onClick(View v) {
            if (v instanceof TextView) {
                String keyword = ((TextView) v).getText().toString().trim();
                searchEdit.setText(keyword);
                searchEdit.setSelection(keyword.length());
            }
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            back_arrow.clearAnimation();
            handler.removeMessages(FEEDKEY_START);
            STATE = 0;
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            handler.removeMessages(FEEDKEY_START);
            STATE = 0;
        }
    
        @Override
        public void onPause() {
            super.onPause();
            handler.removeMessages(FEEDKEY_START);
            STATE = 0;
        }
    
        @Override
        public void onResume() {
            super.onResume();
            if (STATE == 0) {
                keywordsFlow.rubKeywords();
                handler.sendEmptyMessageDelayed(FEEDKEY_START, 3000);
            }
    
        }
    }
      1 import java.util.LinkedList;
      2 import java.util.Random;
      3 import java.util.Vector;
      4 import android.content.Context;
      5 import android.graphics.Color;
      6 import android.graphics.Paint;
      7 import android.util.AttributeSet;
      8 import android.util.Log;
      9 import android.util.TypedValue;
     10 import android.view.Gravity;
     11 import android.view.View;
     12 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
     13 import android.view.animation.AlphaAnimation;
     14 import android.view.animation.Animation;
     15 import android.view.animation.Animation.AnimationListener;
     16 import android.view.animation.AnimationSet;
     17 import android.view.animation.AnimationUtils;
     18 import android.view.animation.Interpolator;
     19 import android.view.animation.ScaleAnimation;
     20 import android.view.animation.TranslateAnimation;
     21 import android.widget.FrameLayout;
     22 import android.widget.TextView;
     23 
     24 public class KeywordsFlow extends FrameLayout implements OnGlobalLayoutListener {
     25     public static final int IDX_X = 0;
     26     public static final int IDX_Y = 1;
     27     public static final int IDX_TXT_LENGTH = 2;
     28     public static final int IDX_DIS_Y = 3;
     29     /** 由外至内的动画。 */
     30     public static final int ANIMATION_IN = 1;
     31     /** 由内至外的动画。 */
     32     public static final int ANIMATION_OUT = 2;
     33     /** 位移动画类型:从外围移动到坐标点。 */
     34     public static final int OUTSIDE_TO_LOCATION = 1;
     35     /** 位移动画类型:从坐标点移动到外围。 */
     36     public static final int LOCATION_TO_OUTSIDE = 2;
     37     /** 位移动画类型:从中心点移动到坐标点。 */
     38     public static final int CENTER_TO_LOCATION = 3;
     39     /** 位移动画类型:从坐标点移动到中心点。 */
     40     public static final int LOCATION_TO_CENTER = 4;
     41     public static final long ANIM_DURATION = 800l;
     42     public static final int MAX = 10;
     43     public static final int TEXT_SIZE_MAX = 21;
     44     public static final int TEXT_SIZE_MIN = 14;
     45     private OnClickListener itemClickListener;
     46     private static Interpolator interpolator;
     47     private static AlphaAnimation animAlpha2Opaque;
     48     private static AlphaAnimation animAlpha2Transparent;
     49     private static ScaleAnimation animScaleLarge2Normal, animScaleNormal2Large,
     50             animScaleZero2Normal, animScaleNormal2Zero;
     51     /** 存储显示的关键字。 */
     52     private Vector<String> vecKeywords;
     53     private int width, height;
     54     /**
     55      * go2Show()中被赋值为true,标识开发人员触发其开始动画显示。<br/>
     56      * 本标识的作用是防止在填充keywrods未完成的过程中获取到width和height后提前启动动画。<br/>
     57      * 在show()方法中其被赋值为false。<br/>
     58      * 真正能够动画显示的另一必要条件:width 和 height不为0。<br/>
     59      */
     60     private boolean enableShow;
     61     private Random random;
     62     /**
     63      * @see ANIMATION_IN
     64      * @see ANIMATION_OUT
     65      * @see OUTSIDE_TO_LOCATION
     66      * @see LOCATION_TO_OUTSIDE
     67      * @see LOCATION_TO_CENTER
     68      * @see CENTER_TO_LOCATION
     69      * */
     70     private int txtAnimInType, txtAnimOutType;
     71     /** 最近一次启动动画显示的时间。 */
     72     private long lastStartAnimationTime;
     73     /** 动画运行时间。 */
     74     private long animDuration;
     75 
     76     public KeywordsFlow(Context context, AttributeSet attrs, int defStyle) {
     77         super(context, attrs, defStyle);
     78         init();
     79     }
     80 
     81     public KeywordsFlow(Context context, AttributeSet attrs) {
     82         super(context, attrs);
     83         init();
     84     }
     85 
     86     public KeywordsFlow(Context context) {
     87         super(context);
     88         init();
     89     }
     90 
     91     private void init() {
     92         lastStartAnimationTime = 0l;
     93         animDuration = ANIM_DURATION;
     94         random = new Random();
     95         vecKeywords = new Vector<String>(MAX);
     96         getViewTreeObserver().addOnGlobalLayoutListener(this);
     97         interpolator = AnimationUtils.loadInterpolator(getContext(),
     98                 android.R.anim.decelerate_interpolator);
     99         animAlpha2Opaque = new AlphaAnimation(0.0f, 1.0f);
    100         animAlpha2Transparent = new AlphaAnimation(1.0f, 0.0f);
    101         animScaleLarge2Normal = new ScaleAnimation(2, 1, 2, 1);
    102         animScaleNormal2Large = new ScaleAnimation(1, 2, 1, 2);
    103         animScaleZero2Normal = new ScaleAnimation(0, 1, 0, 1);
    104         animScaleNormal2Zero = new ScaleAnimation(1, 0, 1, 0);
    105     }
    106 
    107     public long getDuration() {
    108         return animDuration;
    109     }
    110 
    111     public void setDuration(long duration) {
    112         animDuration = duration;
    113     }
    114 
    115     public boolean feedKeyword(String keyword) {
    116         boolean result = false;
    117         if (vecKeywords.size() < MAX) {
    118             result = vecKeywords.add(keyword);
    119         }
    120         return result;
    121     }
    122 
    123     /**
    124      * 开始动画显示。<br/>
    125      * 之前已经存在的TextView将会显示退出动画。<br/>
    126      * 
    127      * @return 正常显示动画返回true;反之为false。返回false原因如下:<br/>
    128      *         1.时间上不允许,受lastStartAnimationTime的制约;<br/>
    129      *         2.未获取到width和height的值。<br/>
    130      */
    131     public boolean go2Show(int animType) {
    132         if (System.currentTimeMillis() - lastStartAnimationTime > animDuration) {
    133             enableShow = true;
    134             if (animType == ANIMATION_IN) {
    135                 txtAnimInType = OUTSIDE_TO_LOCATION;
    136                 txtAnimOutType = LOCATION_TO_CENTER;
    137             } else if (animType == ANIMATION_OUT) {
    138                 txtAnimInType = CENTER_TO_LOCATION;
    139                 txtAnimOutType = LOCATION_TO_OUTSIDE;
    140             }
    141             disapper();
    142             boolean result = show();
    143             return result;
    144         }
    145         return false;
    146     }
    147 
    148     private void disapper() {
    149         int size = getChildCount();
    150         for (int i = size - 1; i >= 0; i--) {
    151             final TextView txt = (TextView) getChildAt(i);
    152             if (txt.getVisibility() == View.GONE) {
    153                 removeView(txt);
    154                 continue;
    155             }
    156             FrameLayout.LayoutParams layParams = (LayoutParams) txt
    157                     .getLayoutParams();
    158             // Log.d("ANDROID_LAB", txt.getText() + " leftM=" +
    159             // layParams.leftMargin + " topM=" + layParams.topMargin
    160             // + " width=" + txt.getWidth());
    161             int[] xy = new int[] { layParams.leftMargin, layParams.topMargin,
    162                     txt.getWidth() };
    163             AnimationSet animSet = getAnimationSet(xy, (width >> 1),
    164                     (height >> 1), txtAnimOutType);
    165             txt.startAnimation(animSet);
    166             animSet.setAnimationListener(new AnimationListener() {
    167                 public void onAnimationStart(Animation animation) {
    168                 }
    169 
    170                 public void onAnimationRepeat(Animation animation) {
    171                 }
    172 
    173                 public void onAnimationEnd(Animation animation) {
    174                     txt.setOnClickListener(null);
    175                     txt.setClickable(false);
    176                     txt.setVisibility(View.GONE);
    177                 }
    178             });
    179         }
    180     }
    181 
    182     private boolean show() {
    183         if (width > 0 && height > 0 && vecKeywords != null
    184                 && vecKeywords.size() > 0 && enableShow) {
    185             enableShow = false;
    186             lastStartAnimationTime = System.currentTimeMillis();
    187             // 找到中心点
    188             int xCenter = width >> 1, yCenter = height >> 1;
    189             // 关键字的个数。
    190             int size = vecKeywords.size();
    191             int xItem = width / size, yItem = height / size;
    192             Log.d("ANDROID_LAB", "--------------------------width=" + width
    193                     + " height=" + height + "  xItem=" + xItem + " yItem="
    194                     + yItem + "---------------------------");
    195             LinkedList<Integer> listX = new LinkedList<Integer>(), listY = new LinkedList<Integer>();
    196             for (int i = 0; i < size; i++) {
    197                 // 准备随机候选数,分别对应x/y轴位置
    198                 listX.add(i * xItem);
    199                 listY.add(i * yItem + (yItem >> 2));
    200                 Log.e("Search", "ListX:" + (i * xItem) + "#listY:"
    201                         + (i * yItem + (yItem >> 2)));
    202             }
    203             // TextView[] txtArr = new TextView[size];
    204             LinkedList<TextView> listTxtTop = new LinkedList<TextView>();
    205             LinkedList<TextView> listTxtBottom = new LinkedList<TextView>();
    206             for (int i = 0; i < size; i++) {
    207                 String keyword = vecKeywords.get(i);
    208                 // 随机颜色
    209                 // int ranColor = 0xff000000 | random.nextInt(0x0077ffff);
    210                 // 随机位置,糙值
    211                 int xy[] = randomXY(random, listX, listY, xItem);
    212                 // 随机字体大小
    213                 int txtSize = TEXT_SIZE_MIN
    214                         + random.nextInt(TEXT_SIZE_MAX - TEXT_SIZE_MIN + 1);
    215                 // 实例化TextView
    216                 final TextView txt = new TextView(getContext());
    217                 txt.setOnClickListener(itemClickListener);
    218                 txt.setText(keyword);
    219                 txt.setTextColor(Color.parseColor("#8cffffff"));
    220                 txt.setTextSize(TypedValue.COMPLEX_UNIT_SP, txtSize);
    221                 txt.setShadowLayer(1, 1, 1, 0xdd696969);
    222                 txt.setGravity(Gravity.CENTER);
    223 
    224                 // txt.setBackgroundColor(Color.RED);
    225                 // 获取文本长度
    226                 Paint paint = txt.getPaint();
    227                 int strWidth = (int) Math.ceil(paint.measureText(keyword));
    228                 xy[IDX_TXT_LENGTH] = strWidth;
    229                 // 第一次修正:修正x坐标
    230                 if (xy[IDX_X] + strWidth > width - (xItem >> 1)) {
    231                     int baseX = width - strWidth;
    232                     // 减少文本右边缘一样的概率
    233                     xy[IDX_X] = baseX - xItem + random.nextInt(xItem >> 1);
    234                 } else if (xy[IDX_X] == 0) {
    235                     // 减少文本左边缘一样的概率
    236                     xy[IDX_X] = Math.max(random.nextInt(xItem), xItem / 3);
    237                 }
    238                 xy[IDX_DIS_Y] = Math.abs(xy[IDX_Y] - yCenter);
    239                 txt.setTag(xy);
    240                 if (xy[IDX_Y] > yCenter) {
    241                     listTxtBottom.add(txt);
    242                 } else {
    243                     listTxtTop.add(txt);
    244                 }
    245             }
    246             attach2Screen(listTxtTop, xCenter, yCenter, yItem);
    247             attach2Screen(listTxtBottom, xCenter, yCenter, yItem);
    248             return true;
    249         }
    250         return false;
    251     }
    252 
    253     /** 修正TextView的Y坐标将将其添加到容器上。 */
    254     private void attach2Screen(LinkedList<TextView> listTxt, int xCenter,
    255             int yCenter, int yItem) {
    256         int size = listTxt.size();
    257         sortXYList(listTxt, size);
    258         for (int i = 0; i < size; i++) {
    259             TextView txt = listTxt.get(i);
    260             int[] iXY = (int[]) txt.getTag();
    261             // Log.d("ANDROID_LAB", "fix[  " + txt.getText() + "  ] x:" +
    262             // iXY[IDX_X] + " y:" + iXY[IDX_Y] + " r2="
    263             // + iXY[IDX_DIS_Y]);
    264             // 第二次修正:修正y坐标
    265             int yDistance = iXY[IDX_Y] - yCenter;
    266             // 对于最靠近中心点的,其值不会大于yItem<br/>
    267             // 对于可以一路下降到中心点的,则该值也是其应调整的大小<br/>
    268             int yMove = Math.abs(yDistance);
    269             inner: for (int k = i - 1; k >= 0; k--) {
    270                 int[] kXY = (int[]) listTxt.get(k).getTag();
    271                 int startX = kXY[IDX_X];
    272                 int endX = startX + kXY[IDX_TXT_LENGTH];
    273                 // y轴以中心点为分隔线,在同一侧
    274                 if (yDistance * (kXY[IDX_Y] - yCenter) > 0) {
    275                     // Log.d("ANDROID_LAB", "compare:" +
    276                     // listTxt.get(k).getText());
    277                     if (isXMixed(startX, endX, iXY[IDX_X], iXY[IDX_X]
    278                             + iXY[IDX_TXT_LENGTH])) {
    279                         int tmpMove = Math.abs(iXY[IDX_Y] - kXY[IDX_Y]);
    280                         if (tmpMove > yItem) {
    281                             yMove = tmpMove;
    282                         } else if (yMove > 0) {
    283                             // 取消默认值。
    284                             yMove = 0;
    285                         }
    286                         // Log.d("ANDROID_LAB", "break");
    287                         break inner;
    288                     }
    289                 }
    290             }
    291             // Log.d("ANDROID_LAB", txt.getText() + " yMove=" + yMove);
    292             if (yMove > yItem) {
    293                 int maxMove = yMove - yItem;
    294                 int randomMove = random.nextInt(maxMove);
    295                 int realMove = Math.max(randomMove, maxMove >> 1) * yDistance
    296                         / Math.abs(yDistance);
    297                 iXY[IDX_Y] = iXY[IDX_Y] - realMove;
    298                 iXY[IDX_DIS_Y] = Math.abs(iXY[IDX_Y] - yCenter);
    299                 // 已经调整过前i个需要再次排序
    300                 sortXYList(listTxt, i + 1);
    301             }
    302             FrameLayout.LayoutParams layParams = new FrameLayout.LayoutParams(
    303                     FrameLayout.LayoutParams.WRAP_CONTENT,
    304                     FrameLayout.LayoutParams.WRAP_CONTENT);
    305             layParams.gravity = Gravity.LEFT | Gravity.TOP;
    306             layParams.leftMargin = iXY[IDX_X];
    307             layParams.topMargin = iXY[IDX_Y];
    308             addView(txt, layParams);
    309             // 动画
    310             AnimationSet animSet = getAnimationSet(iXY, xCenter, yCenter,
    311                     txtAnimInType);
    312             txt.startAnimation(animSet);
    313         }
    314     }
    315 
    316     public AnimationSet getAnimationSet(int[] xy, int xCenter, int yCenter,
    317             int type) {
    318         AnimationSet animSet = new AnimationSet(true);
    319         animSet.setInterpolator(interpolator);
    320         if (type == OUTSIDE_TO_LOCATION) {
    321             animSet.addAnimation(animAlpha2Opaque);
    322             animSet.addAnimation(animScaleLarge2Normal);
    323             TranslateAnimation translate = new TranslateAnimation((xy[IDX_X]
    324                     + (xy[IDX_TXT_LENGTH] >> 1) - xCenter) << 1, 0,
    325                     (xy[IDX_Y] - yCenter) << 1, 0);
    326             animSet.addAnimation(translate);
    327         } else if (type == LOCATION_TO_OUTSIDE) {
    328             animSet.addAnimation(animAlpha2Transparent);
    329             animSet.addAnimation(animScaleNormal2Large);
    330             TranslateAnimation translate = new TranslateAnimation(0, (xy[IDX_X]
    331                     + (xy[IDX_TXT_LENGTH] >> 1) - xCenter) << 1, 0,
    332                     (xy[IDX_Y] - yCenter) << 1);
    333             animSet.addAnimation(translate);
    334         } else if (type == LOCATION_TO_CENTER) {
    335             animSet.addAnimation(animAlpha2Transparent);
    336             animSet.addAnimation(animScaleNormal2Zero);
    337             TranslateAnimation translate = new TranslateAnimation(0,
    338                     (-xy[IDX_X] + xCenter), 0, (-xy[IDX_Y] + yCenter));
    339             animSet.addAnimation(translate);
    340         } else if (type == CENTER_TO_LOCATION) {
    341             animSet.addAnimation(animAlpha2Opaque);
    342             animSet.addAnimation(animScaleZero2Normal);
    343             TranslateAnimation translate = new TranslateAnimation(
    344                     (-xy[IDX_X] + xCenter), 0, (-xy[IDX_Y] + yCenter), 0);
    345             animSet.addAnimation(translate);
    346         }
    347         animSet.setDuration(animDuration);
    348         return animSet;
    349     }
    350 
    351     /**
    352      * 根据与中心点的距离由近到远进行冒泡排序。
    353      * 
    354      * @param endIdx
    355      *            起始位置。
    356      * @param txtArr
    357      *            待排序的数组。
    358      * 
    359      */
    360     private void sortXYList(LinkedList<TextView> listTxt, int endIdx) {
    361         for (int i = 0; i < endIdx; i++) {
    362             for (int k = i + 1; k < endIdx; k++) {
    363                 if (((int[]) listTxt.get(k).getTag())[IDX_DIS_Y] < ((int[]) listTxt
    364                         .get(i).getTag())[IDX_DIS_Y]) {
    365                     TextView iTmp = listTxt.get(i);
    366                     TextView kTmp = listTxt.get(k);
    367                     listTxt.set(i, kTmp);
    368                     listTxt.set(k, iTmp);
    369                 }
    370             }
    371         }
    372     }
    373 
    374     /** A线段与B线段所代表的直线在X轴映射上是否有交集。 */
    375     private boolean isXMixed(int startA, int endA, int startB, int endB) {
    376         boolean result = false;
    377         if (startB >= startA && startB <= endA) {
    378             result = true;
    379         } else if (endB >= startA && endB <= endA) {
    380             result = true;
    381         } else if (startA >= startB && startA <= endB) {
    382             result = true;
    383         } else if (endA >= startB && endA <= endB) {
    384             result = true;
    385         }
    386         return result;
    387     }
    388 
    389     private int[] randomXY(Random ran, LinkedList<Integer> listX,
    390             LinkedList<Integer> listY, int xItem) {
    391         int[] arr = new int[4];
    392         arr[IDX_X] = listX.remove(ran.nextInt(listX.size()));
    393         arr[IDX_Y] = listY.remove(ran.nextInt(listY.size()));
    394         return arr;
    395     }
    396 
    397     public void onGlobalLayout() {
    398         int tmpW = getWidth();
    399         int tmpH = getHeight();
    400         if (width != tmpW || height != tmpH) {
    401             width = tmpW;
    402             height = tmpH;
    403             show();
    404         }
    405     }
    406 
    407     public Vector<String> getKeywords() {
    408         return vecKeywords;
    409     }
    410 
    411     public void rubKeywords() {
    412         vecKeywords.clear();
    413     }
    414 
    415     /** 直接清除所有的TextView。在清除之前不会显示动画。 */
    416     public void rubAllViews() {
    417         removeAllViews();
    418     }
    419 
    420     public void setOnItemClickListener(OnClickListener listener) {
    421         itemClickListener = listener;
    422     }
    431 }
  • 相关阅读:
    前端-【学习心得】-事件委托方法
    [方法] iOS时间戳的转换
    [封装] 修改NSString中部分字段的颜色
    Python3基础16——file对象测试数据的读写与操作
    Python3基础15—— 变量作用域
    Python3基础14——函数&内置函数
    Python3基础13——冒泡排序
    Python3基础12——while循环
    Python3基础11——打印三角形
    Python3基础10——切片(str和list)
  • 原文地址:https://www.cnblogs.com/androidsj/p/4224456.html
Copyright © 2011-2022 走看看