您的位置:首页 > 其它

流式布局SearchFlowLayout

2016-11-01 17:13 281 查看
看到搜索框下面一般都有最近的搜索记录,这些搜索记录一般是流式布局,下面的是一个流式布局,一个继承ViewGroup的自定义view,其中一种使用场景就是在搜索框下面,效果图如下:



下面是SearchFlowLayout的源码:

public class SearchFlowLayout extends ViewGroup {
List<Line> lines = new ArrayList<Line>();//所有的行
private Line currentLine;

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

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

public SearchFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

private OnItemClickListener mListener;

public void setOnItemClickListener(OnItemClickListener listener) {
this.mListener = listener;
}

public interface OnItemClickListener {
void click(int position);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
lines.clear();
currentLine = null;
int width = MeasureSpec.getSize(widthMeasureSpec);
float maxWidth = width - getPaddingLeft() - getPaddingRight();
float horizontalDistance = dp2px(getContext(), 10);
float vercitalDistance = dp2px(getContext(), 10);
int childCount = getChildCount();
currentLine = new Line(maxWidth, horizontalDistance, vercitalDistance);
lines.add(currentLine);
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
final int position = i;
childView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mListener != null) {
mListener.click(position);
}
}
});
measureChild(childView, widthMeasureSpec, heightMeasureSpec);
if (currentLine.canAddView(childView)) {
currentLine.addView(childView);
} else {
currentLine = new Line(maxWidth, horizontalDistance, vercitalDistance);
if (currentLine.canAddView(childView)) {
currentLine.addView(childView);
}
lines.add(currentLine);
}
}

int hight = 0;
for (int i = 0; i < lines.size(); i++) {
if (i == 0) {
hight += getPaddingTop();
} else if (i == lines.size() - 1) {
hight += getPaddingBottom();
}
hight += lines.get(i).mLineHight + vercitalDistance;
}

setMeasuredDimension(width, hight);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int lineTop = getPaddingTop();
for (int i = 0; i < lines.size(); i++) {
Line line = lines.get(i);
line.layout(lineTop);
lineTop += line.mLineHight + line.mVercitalDistance;
}
}

/**
* 每一行
*/
class Line {
public List<View> mViews = new ArrayList<View>();
public float mHorizontalDistance;//行中两个子View之间水平间距
public float mVercitalDistance;//两个行竖直间距
public float mMaxWidth;//行中的最大的宽度
public float mUseWidth;//行中已经使用的宽度
public float mLineHight;//行的高度

public Line(float maxWidth, float horizontalDistance, float vercitalDistance) {
this.mMaxWidth = maxWidth;
this.mHorizontalDistance = horizontalDistance;
this.mVercitalDistance = vercitalDistance;
}

/**
* 是否能添加View
*
* @param view
* @return
*/
private boolean canAddView(View view) {

if (mViews.size() == 0) {
mUseWidth += getPaddingLeft() + getPaddingRight() + view.getMeasuredWidth();
return true;
} else {
mUseWidth += view.getMeasuredWidth() + mHorizontalDistance;
}
if (mUseWidth <= mMaxWidth) {
return true;
}
return false;
}

/**
* 添加View
*
* @param view
*/
private void addView(View view) {
mViews.add(view);
mLineHight = mLineHight < view.getMeasuredHeight() ? view.getMeasuredHeight() : mLineHight;
}

/**
* 摆放子view
*/
private void layout(int lineTop) {
int left = getPaddingLeft();
int top = lineTop;
int right = 0;
int bottom = 0;

for (int i = 0; i < mViews.size(); i++) {
View view = mViews.get(i);
right = left + view.getMeasuredWidth();
bottom = top + view.getMeasuredHeight();

view.layout(left, top, right, bottom);
left += view.getMeasuredWidth() + mHorizontalDistance;

}
}
}

/**
* dp转px
*
* @param context
* @param dp
* @return
*/
public int dp2px(Context context, float dp) {
float density = context.getResources().getDisplayMetrics().density;
int px = (int) (dp * density + 0.5f);
return px;
}
}

使用:
xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:background="#E6E6E6">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:orientation="horizontal"
android:background="@drawable/search_bg"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:layout_gravity="center_vertical"
android:background="@drawable/search1"/>
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
/>
</LinearLayout>
</FrameLayout>
<com.org.sleepgod.widget.SearchFlowLayout
android:id="@+id/fl_view"
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">

</com.org.sleepgod.widget.SearchFlowLayout>
</LinearLayout>

java代码:
public class FlowLayoutActivity extends Activity {

private SearchFlowLayout mSearchFlowLayout;
private String[] mNames = new String[]{"大主宰","龙王传说","一念永恒","雪鹰领主","帝霸","最强狂兵","美食供应商","我是大明星","全职法师","我的贴身校花","重生完美时代"
,"318女生宿舍"};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flowlayout);
mSearchFlowLayout = (SearchFlowLayout) findViewById(R.id.fl_view);
for (int i = 0; i < mNames.length; i++) {
TextView textView = new TextView(this);
textView.setText(mNames[i]);
textView.setBackgroundResource(R.drawable.text_bg);
GradientDrawable gradientDrawable = (GradientDrawable) textView.getBackground();
gradientDrawable.setStroke(1, UIUtils.randomColor());
mSearchFlowLayout.addView(textView);
}

mSearchFlowLayout.setOnItemClickListener(new SearchFlowLayout.OnItemClickListener() {
@Override
public void click(int position) {
Toast.makeText(FlowLayoutActivity.this,mNames[position],Toast.LENGTH_SHORT).show();
}
});
}
}


text_bg
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<stroke
android:width="1dp"
android:color="#61e0fe" />
<padding
android:bottom="6dp"
android:left="10dp"
android:right="10dp"
android:top="6dp" />
<corners android:radius="25dp" />
</shape>

search_bg
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="25dp"/>
<solid android:color="#FFF"/>
<stroke android:color="#7A7A7A"></stroke>
</shape>

源码链接:https://github.com/sleepgodMaster/sleepgod-master/blob/master/src/main/java/com/org/sleepgod/widget/SearchFlowLayout.java
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: