import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class FlowLayout extends ViewGroup {
//
private int usedWidth = 0;
private static final int HORIZONTAL_SPACING = 30;
private static final int VERTICAL_SPACING = 30;
private Line currentLine;
private List<Line> lines = new ArrayList<>();
//
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//
lines.clear();
currentLine = null;
usedWidth = 0;
//
int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
// 测量子view
measureChildren(widthMeasureSpec, heightMeasureSpec);
// 将子view分行 当添加一个子view后,超出Width后,换行,将剩余空间平分给这一行中view;
currentLine = new Line();
for (int i = 0; i < getChildCount(); i++) {
TextView childView = (TextView) getChildAt(i);
int childViewMeasuredWidth = childView.getMeasuredWidth();
usedWidth += childViewMeasuredWidth;
if (usedWidth <= width) {
currentLine.addView(childView);
usedWidth += HORIZONTAL_SPACING;
if (usedWidth > width) {
newline();
}
} else {
newline();
currentLine.addView(childView);
usedWidth += childViewMeasuredWidth;
usedWidth += HORIZONTAL_SPACING;
}
}
if (!lines.contains(currentLine)) {
lines.add(currentLine);
}
int totalHeight = 0;
for (int i = 0; i < lines.size(); i++) {
totalHeight += lines.get(i).getHeight();
}
totalHeight += (lines.size() - 1) * VERTICAL_SPACING;
//
setMeasuredDimension(width + getPaddingLeft() + getPaddingRight(), totalHeight + getPaddingTop() + getPaddingBottom());
}
private void newline() {
lines.add(currentLine);
currentLine = new Line();
usedWidth = 0;
}
// 指定每一行的位置
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
l += getPaddingLeft();
t += getPaddingTop();
for (int i = 0; i < lines.size(); i++) {
Line line = lines.get(i);
line.layout(l, t);
t += line.getHeight();
t += VERTICAL_SPACING;
}
}
private class Line {
private List<View> children = new ArrayList<>();
private int height;
private int lineWidth;
public void addView(View view) {
children.add(view);
if (height < view.getMeasuredHeight()) {
height = view.getMeasuredHeight();
}
lineWidth += view.getMeasuredWidth();
}
public int getHeight() {
return height;
}
// 自定每一行的view位置
public void layout(int l, int t) {
int r = 0;
int ramaind = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - lineWidth - (children.size() - 1) * HORIZONTAL_SPACING;
if (children.size() > 0) {
r = ramaind / children.size();
}
for (int i = 0; i < children.size(); i++) {
View view = children.get(i);
view.layout(l, t, l + view.getMeasuredWidth() + r, t + view.getMeasuredHeight());
l += view.getMeasuredWidth();
l += HORIZONTAL_SPACING;
l += r;
}
}
}
}
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Toast;
/**
* 自定义排序TextView
*/
public class MytextView extends AppCompatTextView {
private Camera camera;
private Matrix matrix;
public MytextView(Context context) {
super(context);
init();
}
public MytextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
camera = new Camera();
matrix = new Matrix();
setOnClickListener(onClickListener);
}
private OnClickListener onClickListener =new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), getText().toString(), Toast.LENGTH_SHORT).show();
show=true;
invalidate();
}
};
protected boolean show;
private final static int FPS = 1000 / 60;
private int degrees=0;
@Override
public void draw(Canvas canvas) {
// 绕X轴3d旋转
if(show && degrees<=360){
int cx = getWidth()/2;
int cy = getHeight()/2;
camera.save();
camera.rotateX(degrees);
camera.getMatrix(matrix);
camera.restore();
//
matrix.preTranslate(-cx,-cy);
matrix.postTranslate(cx,cy);
//
canvas.concat(matrix);
degrees+=20;
postInvalidateDelayed(FPS);
}else{
degrees=0;
}
super.draw(canvas);
}
@Override
protected void onDraw(Canvas canvas) {
// 添加剩余空间后,字体不居中,移动canvas 字体居中
int width = getWidth();
float text_with = getPaint().measureText(getText().toString());
canvas.translate((width-text_with-getPaddingLeft()-getPaddingRight())/2,0);
super.onDraw(canvas);
//
}
public class RankingActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView();
}
private void initView() {
//初始化view
ScrollView scrollView = new ScrollView(this);
FlowLayout layout = new FlowLayout(this);
int padding = 20;
layout.setPadding(padding,padding,padding,padding);
scrollView.addView(layout);
TextView textView = null;
Random random = new Random();
int backColor = 0xffcecece;
int textPaddingV = 12;
int textPaddingH = 10;
for (int i = 0; i < Images.rank.length; i++) {
final String text = Images.rank[i];
textView = new MytextView(this);
textView.setText(text);
// 随机选择背景颜色
int red = random.nextInt(188)+20;
int green = random.nextInt(188) + 20;
int blue = random.nextInt(188) + 20;
int color = Color.rgb(red, green, blue);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP,20);
textView.setBackground(createStateListDrawable(createShape(backColor), createShape(color)));
textView.setTextColor(Color.WHITE);
textView.setPadding(textPaddingH, textPaddingV, textPaddingH, textPaddingV);
layout.addView(textView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, -2));
}
setContentView(scrollView);
}
public StateListDrawable createStateListDrawable(Drawable pressedDrawable, Drawable normalDrawable){
StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[]{android.R.attr.state_pressed},pressedDrawable);
stateListDrawable.addState(new int[]{},normalDrawable);
return stateListDrawable;
}
public GradientDrawable createShape(int color){
GradientDrawable drawable = new GradientDrawable();
drawable.setCornerRadius(10);
drawable.setColor(color);
return drawable;
}
