Android 사용자 정의 ViewGroup 탭 스 트림 용기 FlowLayout 구현

이 글 은 안 드 로 이 드 사용자 정의 View Group 의 실현 태그 스 트림 레이아웃-Flow Layout 를 다 루 고 있 습 니 다.개발 과정 에서 우 리 는 인기 태그 등 자동 으로 줄 을 바 꾸 는 스 트림 레이아웃 기능 을 실현 해 야 합 니 다.인터넷 에 도 이러한 Flow Layout 가 많 지만 제 학습 습관 에 영향 을 주지 않 습 니 다.여느 때 와 마찬가지 로 사용자 정의 View Group 의 개발 과정 과 주의해 야 할 부분 을 정리 하고 싶 습 니 다.
관례 에 따라 우 리 는 먼저 효과 도 를 살 펴 보 자.

1.코드 를 쓰기 전에 몇 가지 문 제 는 우리 가 먼저 알 아야 할 것 이다.
1.ViewGroup 이란 무엇 입 니까?이름 으로 볼 때 컨트롤 그룹 으로 번역 할 수 있 습 니 다.즉,ViewGroup 내부 에 여러 개의 컨트롤 이 포함 되 어 있 고 하나의 View 라 는 뜻 입 니 다.Android 의 디자인 에서 ViewGroup 도 View 를 계승 했다.이것 은 View 자체 가 하나의 컨트롤 일 수도 있 고 여러 개의 컨트롤 로 구 성 된 컨트롤 일 수도 있다 는 것 을 의미한다.
2.View Group 의 종류:흔히 볼 수 있 는 것 은 LinearLayout,RelativeLayout,FrameLayout,AbsoluteLayout,GirdLayout,TableLayout 이다.그 중에서 LinearLayout 와 RelativeLayout 가 가장 많이 사용 하 는 두 가지;
3.View Group 의 직책:childView 에 건의 하 는 너비 와 높이 와 측정 모델 을 계산 한 다음 에 childView 의 위 치 를 결정 합 니 다.
4.스 트림 레이아웃(FlowLayout)이 무엇 인지 말 합 니 다.컨트롤 은 ViewGroup 의 너비 에 따라 자동 으로 왼쪽 에서 오른쪽으로 추 가 됩 니 다.현재 줄 에 이 하위 뷰 를 놓 을 수 있다 면 현재 줄 에 놓 으 십시오.현재 줄 에 남 은 공간 이 이 하위 뷰 를 수용 하 는 데 부족 하면 다음 줄 의 맨 왼쪽 에 자동 으로 추 가 됩 니 다.
2.사용자 정의 ViewGroup 의 절 차 를 정리 합 니 다.
1.사용자 정의 ViewGroup 의 속성
2.ViewGroup 의 구조 방법 에서 사용자 정의 속성 을 얻 을 수 있 습 니 다.
3.onMesure 재 작성
4.onLayout 재 작성
3.ViewGroup 의 몇 가지 구조 함수:
1、public FlowLayout(Context context)
―>자바 코드 가 new 하나의 FlowLayout 인 스 턴 스 를 직접 사용 할 때 하나의 매개 변수 만 있 는 구조 함 수 를 호출 합 니 다.
2、public FlowLayout(Context context, AttributeSet attrs)
->기본 XML 레이아웃 파일 에서 만 들 때 두 개의 인자 가 있 는 구조 함 수 를 호출 합 니 다.AttributeSet 형식의 인 자 는 XML 레이아웃 파일 에서 사용자 정의 속성 을 AttributeSet 을 통 해 View 에 가 져 옵 니 다.
3、public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr)
->구조 함수 에서 세 번 째 인 자 는 기본 Style 입 니 다.여기 서 기본 Style 은 현재 application 이나 Activity 에서 사용 하 는 Theme 의 기본 Style 을 말 하 며 명확 하 게 호출 될 때 만 호출 됩 니 다.
4、public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
―이 구조 함 수 는 API 21 에 추 가 된 것 이다
4.사용자 정의 View Group 의 주요 코드 를 살 펴 보 겠 습 니 다.
 1.ViewGroup 의 속성 을 사용자 정의 합 니 다.먼저 res/values/에서 attr.xml 를 만 들 고 우리 가 필요 로 하 는 속성 과 해당 속성 을 설명 하 는 수치 유형 을 정의 합 니 다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <!--  item    -->
 <attr name="verticalSpacing" format="dimension" />
 <!--   item    -->
 <attr name="horizontalSpacing" format="dimension" />

 <declare-styleable name="FlowLayout">
 <attr name="verticalSpacing" />
 <attr name="horizontalSpacing" />
 </declare-styleable>

</resources>

저 희 는 vertical Spacing 과 horizontal Spacing 2 개의 속성 을 정 의 했 습 니 다.각각 탭 간 의 수직 간격 과 가로 간격 을 표시 합 니 다.그 중에서 format 는 이 속성의 수치 유형 이 고 format 수치 유형 은 모두 10 가지 가 있 습 니 다.이 는 string,color,demension,integer,enum,reference,float,boolean,fraction 과 flag 를 포함 합 니 다.
2.그리고 XML 레이아웃 에서 사용자 정의 View 를 설명 합 니 다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:custom="http://schemas.android.com/apk/res-auto"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">

 <TextView
 android:layout_width="match_parent"
 android:layout_height="48dp"
 android:background="#38353D"
 android:gravity="center"
 android:text="  "
 android:textColor="@android:color/white"
 android:textSize="16dp" />

 <ScrollView
 android:layout_width="match_parent"
 android:layout_height="wrap_content">

 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="vertical">

 <TextView
 android:id="@+id/tv_remind"
 android:layout_width="match_parent"
 android:layout_height="46dp"
 android:background="@android:color/white"
 android:gravity="center_vertical"
 android:paddingLeft="15dp"
 android:text="    (  5 ) "
 android:textSize="16dp" />

 <com.per.flowlayoutdome.FlowLayout
 android:id="@+id/tcy_my_label"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="@android:color/white"
 android:padding="5dp"
 android:visibility="gone"
 custom:horizontalSpacing="6dp"
 custom:verticalSpacing="12dp" />

 <View
 android:layout_width="match_parent"
 android:layout_height="10dp"
 android:background="#f6f6f6" />

 <RelativeLayout
 android:layout_width="match_parent"
 android:layout_height="46dp"
 android:background="@android:color/white">

 <TextView
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_centerVertical="true"
  android:paddingLeft="15dp"
  android:text="     "
  android:textSize="16dp" />
 </RelativeLayout>

 <View
 android:layout_width="match_parent"
 android:layout_height="1dp"
 android:background="#f6f6f6" />

 <com.per.flowlayoutdome.FlowLayout
 android:id="@+id/tcy_hot_label"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="@android:color/white"
 android:padding="5dp"
 custom:horizontalSpacing="6dp"
 custom:verticalSpacing="12dp" />
 </LinearLayout>
 </ScrollView>
</LinearLayout>

반드시 xmlns:custom="을 도입 해 야 합 니 다.http://schemas.android.com/apk/res-auto"Android Studio 에서 res-atuo 네 임 스페이스 를 사용 할 수 있 습 니 다.사용자 정의 View 전체 이름 을 추가 하지 않 아 도 됩 니 다."
3.View 의 구조 방법 에서 사용자 정의 스타일 을 얻 을 수 있 습 니 다.

/**
 *   item    
 */
 private int mVerticalSpacing;
 /**
 *   item    
 */
 private int mHorizontalSpacing;

 public FlowLayout(Context context) {
 this(context, null);
 }

 public FlowLayout(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }

 public FlowLayout(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 /**
 *                
 */
 TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.FlowLayout, defStyle, 0);
 for (int i = 0; i < a.getIndexCount(); i++) {
 int attr = a.getIndex(i);
 switch (attr) {
 case R.styleable.FlowLayout_verticalSpacing:
  mVerticalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_verticalSpacing, 5);
  break;
 case R.styleable.FlowLayout_horizontalSpacing:
  mHorizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_horizontalSpacing, 10);
  break;
 }
 }
 a.recycle();
 }

우 리 는 세 가지 구조 방법 을 다시 썼 다.위의 구조 방법 에서 기본 적 인 구조 파일 은 두 개의 매개 변수의 구조 방법 을 호출 하 는 것 이 라 고 말 했 기 때문에 모든 구조 방법 에 세 개의 매개 변수의 구조 방법 을 호출 한 다음 에 세 개의 매개 변수의 구조 방법 에서 자정 의 속성 을 얻 도록 하 는 것 을 기억 해 야 한다.
처음에 하나의 매개 변수의 구조 방법 과 두 개의 매개 변수의 구조 방법 은 다음 과 같다.

 public FlowLayout(Context context) {
 super(context);
 }

 public FlowLayout(Context context, AttributeSet attrs) {
 super(context, attrs);
 }

한 가지 주의해 야 할 것 은 슈퍼 가 this 로 바 꾼 다음 에 하나의 매개 변수의 구조 방법 으로 두 매개 변수의 구조 방법 을 인용 하 게 해 야 한 다 는 것 이다.두 매개 변수의 구조 방법 은 세 개의 매개 변수의 구조 방법 을 인용 하고 코드 는 다음 과 같다.

 public FlowLayout(Context context) {
 this(context, null);
 }

 public FlowLayout(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }

4.onMesure 재 작성 방법

/**
 *                                
 */
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 /**
 *    ViewGroup            ,      
 */
 int heighMode = MeasureSpec.getMode(heightMeasureSpec);
 int heighSize = MeasureSpec.getSize(heightMeasureSpec);
 int widthSize = MeasureSpec.getSize(widthMeasureSpec);
 /**
 *  
 */
 int height = 0;
 /**
 *       ,   height
 */
 int lineHeight = 0;
 /**
 *  warp_content   ,    childView        
 */
 int childLeft = getPaddingLeft();
 /**
 *  warp_content   ,    childView        
 */
 int childTop = getPaddingTop();
 // getChildCount   view   ,        View
 for (int i = 0; i < getChildCount(); i++) {
 //  index   view
 View childView = getChildAt(i);
 //      child    
 measureChild(childView, widthMeasureSpec, heightMeasureSpec);
 //            
 int childHeight = childView.getMeasuredHeight();
 //            
 int childWidth = childView.getMeasuredWidth();
 lineHeight = Math.max(childHeight, lineHeight);//     
 //      childView,      ,         width,  height       
 if (childWidth + childLeft + getPaddingRight() > widthSize) {
 childLeft = getPaddingLeft();//       ,    childLeft
 childTop += mVerticalSpacing + childHeight;//        
 lineHeight = childHeight;//           
 }else{
 //      childView   
 childLeft += childWidth + mHorizontalSpacing;
 }
 }
 height += childTop + lineHeight + getPaddingBottom();
 setMeasuredDimension(widthSize, heighMode == MeasureSpec.EXACTLY ? heighSize : height);
 }

먼저 부모 용기 에 들 어 오 는 측정 모드 와 너비 가 높 은 계산 치 를 얻 은 다음 모든 childView 를 옮 겨 다 니 며 measure Child 방법 으로 모든 childView 를 측정 합 니 다.그리고 모든 childView 의 측정 에 따라 이 ViewGroup 을 wrap 로 설정 하면콘 텐 츠 높이.마지막 으로 모드 에 따라 Measure Spec.EXACTLY 라면 부모 View Group 에서 들 어 오 는 높이 를 직접 사용 합 니 다.그렇지 않 으 면 자신 이 계산 하 는 높이 로 설정 하고 세심 한 친구 가'거기 가 넓 냐'고 물 을 것 입 니 다.여기 서 우 리 는 기본적으로 너비 가 Measure Spec.EXACTLY 모드 입 니 다.
5.onLayout 재 작성 방법

@Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
 int width = r - l;
 int childLeft = getPaddingLeft();
 int childTop = getPaddingTop();
 int lineHeight = 0;
 //    childView      ,            
 for (int i = 0; i < getChildCount(); i++) {
 final View childView = getChildAt(i);
 if (childView.getVisibility() == View.GONE) {
 continue;
 }
 int childWidth = childView.getMeasuredWidth();
 int childHeight = childView.getMeasuredHeight();
 lineHeight = Math.max(childHeight, lineHeight);
 //         
 if (childLeft + childWidth + getPaddingRight() > width) {
 childLeft = getPaddingLeft();
 childTop += mVerticalSpacing + lineHeight;
 lineHeight = childHeight;
 }
 childView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
 childLeft += childWidth + mHorizontalSpacing;
 }
 }

onLayout 에서 모든 childView 의 위치 와 크기 에 대한 지정 이 완료 되 었 습 니 다.
6.여기 서 저 희 는 사용자 정의 View Group 의 코드 를 다 썼 습 니 다.몇 가지 주의해 야 할 것 이 있 습 니 다.
(1)getChildAt(int index):index 의 하위 view 를 얻 습 니 다.
(2)getChildCount():모든 하위 view 의 수 를 얻 습 니 다.
(3)measure Child(childView,width MeasureSpec,height MeasureSpec):하위 view 자체 의 측정 방법 을 사용 하여 모든 child 의 너비 와 높이 를 측정 합 니 다.
테마 로 돌 아 왔 습 니 다.이제 사용자 정의 View Group 을 통 해 Flow Layout 를 실현 하 는 부분 을 완 성 했 습 니 다.다음은 논리 코드 입 니 다.
5.다음은 논리 코드 입 니 다.
1.저 는 FlowLayout 안의 완전한 코드 를 붙 입 니 다.

package com.per.flowlayoutdome;

import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

/**
 * @author: xiaolijuan
 * @description:     -     
 * @projectName: FlowLayoutDome
 * @date: 2016-06-16
 * @time: 16:21
 */
public class FlowLayout extends ViewGroup{
 /**
 *   item    
 */
 private int mVerticalSpacing;
 /**
 *   item    
 */
 private int mHorizontalSpacing;
 private BaseAdapter mAdapter;
 private TagItemClickListener mListener;
 private DataChangeObserver mObserver;

 public FlowLayout(Context context) {
 this(context, null);
 }

 public FlowLayout(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }

 public FlowLayout(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 /**
 *                
 */
 TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.FlowLayout, defStyle, 0);
 for (int i = 0; i < a.getIndexCount(); i++) {
 int attr = a.getIndex(i);
 switch (attr) {
 case R.styleable.FlowLayout_verticalSpacing:
  mVerticalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_verticalSpacing, 5);
  break;
 case R.styleable.FlowLayout_horizontalSpacing:
  mHorizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_horizontalSpacing, 10);
  break;
 }
 }
 a.recycle();
 }

 /**
 *                                
 */
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 /**
 *    ViewGroup            ,      
 */
 int heighMode = MeasureSpec.getMode(heightMeasureSpec);
 int heighSize = MeasureSpec.getSize(heightMeasureSpec);
 int widthSize = MeasureSpec.getSize(widthMeasureSpec);
 /**
 *  
 */
 int height = 0;
 /**
 *       ,   height
 */
 int lineHeight = 0;
 /**
 *  warp_content   ,    childView        
 */
 int childLeft = getPaddingLeft();
 /**
 *  warp_content   ,    childView        
 */
 int childTop = getPaddingTop();
 // getChildCount   view   ,        View
 for (int i = 0; i < getChildCount(); i++) {
 //  index   view
 View childView = getChildAt(i);
 //      child    
 measureChild(childView, widthMeasureSpec, heightMeasureSpec);
 //            
 int childHeight = childView.getMeasuredHeight();
 //            
 int childWidth = childView.getMeasuredWidth();
 lineHeight = Math.max(childHeight, lineHeight);//     
 //      childView,      ,         width,  height       
 if (childWidth + childLeft + getPaddingRight() > widthSize) {
 childLeft = getPaddingLeft();//       ,    childLeft
 childTop += mVerticalSpacing + childHeight;//        
 lineHeight = childHeight;//           
 }else{
 //      childView   
 childLeft += childWidth + mHorizontalSpacing;
 }
 }
 height += childTop + lineHeight + getPaddingBottom();
 setMeasuredDimension(widthSize, heighMode == MeasureSpec.EXACTLY ? heighSize : height);
 }

 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
 int width = r - l;
 int childLeft = getPaddingLeft();
 int childTop = getPaddingTop();
 int lineHeight = 0;
 //    childView      ,            
 for (int i = 0; i < getChildCount(); i++) {
 final View childView = getChildAt(i);
 if (childView.getVisibility() == View.GONE) {
 continue;
 }
 int childWidth = childView.getMeasuredWidth();
 int childHeight = childView.getMeasuredHeight();
 lineHeight = Math.max(childHeight, lineHeight);
 //         
 if (childLeft + childWidth + getPaddingRight() > width) {
 childLeft = getPaddingLeft();
 childTop += mVerticalSpacing + lineHeight;
 lineHeight = childHeight;
 }
 childView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
 childLeft += childWidth + mHorizontalSpacing;
 }
 }

 private void drawLayout() {
 if (mAdapter == null || mAdapter.getCount() == 0) {
 return;
 }
 removeAllViews();
 for (int i = 0; i < mAdapter.getCount(); i++) {
 View view = mAdapter.getView(i, null, null);
 final int position = i;
 view.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
  if (mListener != null) {
  mListener.itemClick(position);
  }
 }
 });
 addView(view);
 }
 }

 public void setAdapter(BaseAdapter adapter) {
 if (mAdapter == null) {
 mAdapter = adapter;
 if (mObserver == null) {
 mObserver = new DataChangeObserver();
 mAdapter.registerDataSetObserver(mObserver);
 }
 drawLayout();
 }
 }

 public void setItemClickListener(TagItemClickListener mListener) {
 this.mListener = mListener;
 }

 public interface TagItemClickListener {
 void itemClick(int position);
 }

 class DataChangeObserver extends DataSetObserver {
 @Override
 public void onChanged() {
 drawLayout();
 }

 @Override
 public void onInvalidated() {
 super.onInvalidated();
 }
 }
}

2、FlowLayoutAdapter

package com.per.flowlayoutdome;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;

import java.util.List;

/**
 * @author: adan
 * @description:        
 * @projectName: FlowLayoutDome
 * @date: 2016-06-16
 * @time: 16:22
 */
public class FlowLayoutAdapter extends BaseAdapter {

 private Context mContext;
 private List<String> mList;

 public FlowLayoutAdapter(Context context, List<String> list) {
 mContext = context;
 mList = list;
 }

 @Override
 public int getCount() {
 return mList.size();
 }

 @Override
 public String getItem(int position) {
 return mList.get(position);
 }

 @Override
 public long getItemId(int position) {
 return position;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
 ViewHolder holder;
 if (convertView == null) {
 convertView = LayoutInflater.from(mContext).inflate(
  R.layout.item_tag, null);
 holder = new ViewHolder();
 holder.mBtnTag = (Button) convertView.findViewById(R.id.btn_tag);
 convertView.setTag(holder);
 } else {
 holder = (ViewHolder) convertView.getTag();
 }
 holder.mBtnTag.setText(getItem(position));
 return convertView;
 }

 static class ViewHolder {
 Button mBtnTag;
 }
}

3、MainActivity

package com.per.flowlayoutdome;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends Activity {
 private TextView tv_remind;

 private FlowLayout tcy_my_label, tcy_hot_label;
 private FlowLayoutAdapter mMyLabelAdapter, mHotLabelAdapter;
 private List<String> MyLabelLists, HotLabelLists;

 private static int TAG_REQUESTCODE = 0x101;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 initView();
 initData();
 }

 private void initView() {
 tv_remind = (TextView) findViewById(R.id.tv_remind);
 tcy_my_label = (FlowLayout) findViewById(R.id.tcy_my_label);
 tcy_hot_label = (FlowLayout) findViewById(R.id.tcy_hot_label);
 }

 private void initData() {
 String[] date = getResources().getStringArray(R.array.tags);
 HotLabelLists = new ArrayList<>();
 for (int i = 0; i < date.length; i++) {
 HotLabelLists.add(date[i]);
 }
 mHotLabelAdapter = new FlowLayoutAdapter(this, HotLabelLists);
 tcy_hot_label.setAdapter(mHotLabelAdapter);
 tcy_hot_label.setItemClickListener(new TagCloudLayoutItemOnClick(1));

 MyLabelLists = new ArrayList<>();
 mMyLabelAdapter = new FlowLayoutAdapter(this, MyLabelLists);
 tcy_my_label.setAdapter(mMyLabelAdapter);
 tcy_my_label.setItemClickListener(new TagCloudLayoutItemOnClick(0));

 String labels = String.valueOf(getIntent().getStringExtra("labels"));
 if (!TextUtils.isEmpty(labels) && labels.length() > 0
 && !labels.equals("null")) {
 String[] temp = labels.split(",");
 for (int i = 0; i < temp.length; i++) {
 MyLabelLists.add(temp[i]);
 }
 ChangeMyLabels();
 }

 }

 /**
 *         
 */
 private void ChangeMyLabels() {
 tv_remind.setVisibility(MyLabelLists.size() > 0 ? View.GONE
 : View.VISIBLE);
 tcy_my_label.setVisibility(MyLabelLists.size() > 0 ? View.VISIBLE
 : View.GONE);
 mMyLabelAdapter.notifyDataSetChanged();
 }

 /**
 *        
 *
 * @author lijuan
 */
 class TagCloudLayoutItemOnClick implements FlowLayout.TagItemClickListener {
 int index;

 public TagCloudLayoutItemOnClick(int index) {
 this.index = index;
 }

 @Override
 public void itemClick(int position) {
 switch (index) {
 case 0:
  MyLabelLists.remove(MyLabelLists.get(position));
  ChangeMyLabels();
  break;
 case 1:
  if (MyLabelLists.size() < 5) {
  if (HotLabelLists.get(position).equals("   ")) {
  startActivityForResult(
   new Intent(MainActivity.this,
   AddTagActivity.class),
   TAG_REQUESTCODE);
  } else {
  Boolean isExits = isExist(MyLabelLists,
   HotLabelLists.get(position));
  if (isExits) {
  Toast.makeText(MainActivity.this, "        ", Toast.LENGTH_LONG).show();
  return;
  }
  MyLabelLists.add(HotLabelLists.get(position));
  ChangeMyLabels();
  }
  } else {
  Toast.makeText(MainActivity.this, "      5   ", Toast.LENGTH_LONG).show();
  }
  break;
 default:
  break;
 }
 }
 }

 /**
 *              ,         
 *
 * @param str
 * @param compareStr
 * @return
 */
 public static Boolean isExist(List<String> str, String compareStr) {
 Boolean isExist = false;//  ]     
 for (int i = 0; i < str.size(); i++) {
 if (compareStr.equals(str.get(i))) {
 isExist = true;
 }
 }
 return isExist;
 }

 /**
 *     
 */
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 if (TAG_REQUESTCODE == requestCode) {
 if (resultCode == AddTagActivity.TAG_RESULTCODE) {
 String label = data.getStringExtra("tags");
 MyLabelLists.add(label);
 ChangeMyLabels();
 }
 }
 }
}

4、AddTagActivity

package com.per.flowlayoutdome;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

/**
 * @author: xiaolijuan
 * @description:        
 * @date: 2016-06-10
 * @time: 14:37
 */
public class AddTagActivity extends Activity implements View.OnClickListener{

 private EditText mEtLabel;
 private Button mBtnSure;
 public final static int TAG_RESULTCODE = 0x102;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_add_tag);
 initView();
 initData();
 }

 private void initData() {
 //                       
 mEtLabel.addTextChangedListener(new TextWatcher_Enum());
 }

 private void initView() {
 mEtLabel = (EditText) findViewById(R.id.et_label);
 mBtnSure = (Button) findViewById(R.id.btn_sure);

 mBtnSure.setOnClickListener(this);
 }

 @Override
 public void onClick(View v) {
 switch (v.getId()) {
 case R.id.btn_sure:
 String label = mEtLabel.getText().toString();
 if (TextUtils.isEmpty(label)) {
  Toast.makeText(AddTagActivity.this,"         ",Toast.LENGTH_LONG).show();
  return;
 }
 Intent intent = getIntent();
 intent.putExtra("tags", label);
 setResult(TAG_RESULTCODE, intent);
 finish();
 break;
 }
 }

 /**
 *              8      ,           8  
 *
 * @author lijuan
 *
 */
 class TextWatcher_Enum implements TextWatcher {
 @Override
 public void beforeTextChanged(CharSequence s, int start, int count,
   int after) {
 }

 @Override
 public void onTextChanged(CharSequence s, int start, int before,
   int count) {
 int lenght = mEtLabel.getText().toString().trim().length();
 if (lenght > 8) {
 Toast.makeText(AddTagActivity.this,"         8  ",Toast.LENGTH_LONG).show();
 }
 }

 @Override
 public void afterTextChanged(Editable s) {

 }
 }
}

5、activity_main.xml 이 위 에 붙 어 있 습 니 다.여기 서 중복 되 지 않 습 니 다.저 희 는 arrays.xml 을 만 들 었 습 니 다.여기 서 인기 있 는 탭 을 정의 합 니 다.

<?xml version="1.0" encoding="UTF-8"?>
<resources>

 <string-array name="tags">
 <item>  </item>
 <item>  </item>
 <item>  </item>
 <item>   </item>
 <item>    </item>
 <item>  </item>
 <item>  </item>
 <item>   </item>
 <item>   </item>
 <item>  </item>
 <item>  </item>
 <item>  </item>
 <item>  </item>
 <item>   </item>
 <item>    </item>
 <item>   </item>
 <item>  </item>
 <item>   </item>
 <item>   </item>
 </string-array>

</resources>

6、item_tag.xml

<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/btn_tag"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:background="@drawable/selector_btn_item"
 android:gravity="center"
 android:minHeight="30dp"
 android:minWidth="45dp"
 android:paddingLeft="16dp"
 android:paddingRight="16dp"
 android:textSize="12sp" />

6、activity_add_tag.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="250dp"
 android:layout_height="wrap_content"
 android:background="@android:color/white"
 android:gravity="center_horizontal"
 android:orientation="vertical"
 android:padding="5dp" >

 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="vertical" >

 <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginLeft="5dp"
 android:text="          "
 android:textColor="@android:color/black"
 android:textSize="16dp" />

 <EditText
 android:id="@+id/et_label"
 android:layout_width="match_parent"
 android:layout_height="80dp"
 android:layout_margin="5dp"
 android:background="@drawable/selector_btn_item"
 android:gravity="center_vertical|start"
 android:maxLength="8"
 android:paddingLeft="10dp"
 android:textColor="@android:color/black"
 android:textSize="16dp" />
 </LinearLayout>

 <Button
 android:id="@+id/btn_sure"
 android:layout_width="50dp"
 android:layout_height="32dp"
 android:layout_marginLeft="16dp"
 android:layout_marginRight="16dp"
 android:layout_marginTop="5dp"
 android:background="#38353D"
 android:gravity="center"
 android:text="  "
 android:textColor="@android:color/white"
 android:textSize="14dp" />

</LinearLayout>

7、selector_btn_item.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="#ff76787b" />
 <corners android:bottomLeftRadius="5dp" android:bottomRightRadius="5dp" android:topLeftRadius="5dp" android:topRightRadius="5dp" />
 <stroke android:width="1px" android:color="#ffd1d1d1" />
 </shape>
 </item>
 <item>
 <shape>
 <solid android:color="#ffffff" />
 <corners android:bottomLeftRadius="2.5dp" android:bottomRightRadius="2.5dp" android:topLeftRadius="2.5dp" android:topRightRadius="2.5dp" />
 <stroke android:width="0.5px" android:color="#ffd1d1d1" />
 </shape>
 </item>
</selector>

마지막 이 죠?AndroidManifest.xml 에 추가 해 야 합 니 다.

<activity
 android:name=".AddTagActivity"
 android:theme="@style/dialogstyle" />

사용자 정의 탭,팝 업 대화 상자 와 유사 한 Activity 를 사용 합 니 다.사용자 정의 스타일 을 참조 합 니 다.

<style name="dialogstyle">
 <!--  dialog   -->
 <item name="android:windowBackground">@android:color/transparent</item>
 <!--  Dialog windowFrame   -->
 <item name="android:windowFrame">@null</item>
 <!--     -->
 <item name="android:windowNoTitle">true</item>
 <!--     activity  -->
 <item name="android:windowIsFloating">true</item>
 <!--     -->
 <item name="android:windowIsTranslucent">true</item>
 <!--         -->
 <item name="android:windowContentOverlay">@null</item>
 <!--    ,            Animation.Dialog-->
 <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
 <!--        -->
 <item name="android:backgroundDimEnabled">true</item>
 </style>

대화 상자 와 유사 한 Activity 에 대해 모 르 는 것 이 있 으 면 이전 글 에 올 라 갈 수 있 습 니 다.
원본 다운로드:Android 에 서 는 Dialog 스타일 팝 업 상자 의 Activity 를 사용 합 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기