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; }