15.瀑布流、测量

排行界面

TopProtocol :json数据就是写字符串,所以不需要写bean对象
  1. public class TopProtocol extends BaseProtocol<List<String>> {
  2. @Override
  3. public List<String> paserJson(String json) {
  4. List<String> datas=new ArrayList<String>();
  5. try {
  6. JSONArray array=new JSONArray(json);
  7. for(int i=0;i<array.length();i++){
  8. String str=array.getString(i);
  9. datas.add(str);
  10. }
  11. return datas;
  12. } catch (JSONException e) {
  13. e.printStackTrace();
  14. return null;
  15. }
  16. }
  17. @Override
  18. public String getKey() {
  19. return "hot";
  20. }
  21. }
DrawableUtils :用代码创建状态选择器 和圆角
  1. public class DrawableUtils {
  2. public static GradientDrawable createShape(int color){
  3. GradientDrawable drawable=new GradientDrawable();//相当于shape
  4. drawable.setCornerRadius(UiUtils.dip2px(5));//设置4个角的弧度
  5. drawable.setColor(color);// 设置颜色
  6. return drawable;
  7. }
  8. public static StateListDrawable createSelectorDrawable(Drawable pressedDrawable,Drawable normalDrawable){
  9. // <selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="200">
  10. // <item android:state_pressed="true" android:drawable="@drawable/detail_btn_pressed"></item>
  11. // <item android:drawable="@drawable/detail_btn_normal"></item>
  12. // </selector>
  13. StateListDrawable stateListDrawable=new StateListDrawable();
  14. stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, pressedDrawable);// 按下显示的图片
  15. stateListDrawable.addState(new int[]{}, normalDrawable);// 抬起显示的图片
  16. return stateListDrawable;
  17. }
  18. }
TopFragment :使用代码创建、随机色
MATCH_PARENT 、FILL_PARENT是-1且他俩个没有任何区别,WRAP_CONTENT是-2 
  1. public class TopFragment extends BaseFragment {
  2. private List<String> datas;
  3. @Override
  4. public View createSuccessView() {
  5. ScrollView scrollView=new ScrollView(UiUtils.getContext());
  6. scrollView.setBackgroundResource(R.drawable.grid_item_bg_normal);
  7. LinearLayout layout=new LinearLayout(UiUtils.getContext());
  8. int padding=UiUtils.dip2px(13);
  9. layout.setPadding(padding, padding, padding, padding);
  10. layout.setOrientation(LinearLayout.VERTICAL);// 设置线性布局的方向
  11. int backColor = 0xffcecece;
  12. Drawable pressedDrawable=DrawableUtils.createShape(backColor);// 按下显示的图片
  13. for(int i=0;i<datas.size();i++){
  14. TextView textView=new TextView(UiUtils.getContext());
  15. final String str=datas.get(i);
  16. textView.setText(str);
  17. Random random=new Random(); //创建随机
  18. int red = random.nextInt(200)+22;
  19. int green = random.nextInt(200)+22;
  20. int blue = random.nextInt(200)+22;//有可能都是0或255成白色或者黑色了
  21. int color=Color.rgb(red, green, blue);//范围 0-255
  22. GradientDrawable createShape = DrawableUtils.createShape(color); // 默认显示的图片
  23. StateListDrawable createSelectorDrawable = DrawableUtils.createSelectorDrawable(pressedDrawable, createShape);// 创建状态选择器
  24. textView.setBackgroundDrawable(createSelectorDrawable);
  25. textView.setTextColor(Color.WHITE);
  26. //textView.setTextSize(UiUtils.dip2px(14));
  27. int textPaddingV = UiUtils.dip2px(4);
  28. int textPaddingH = UiUtils.dip2px(7);
  29. textView.setPadding(textPaddingH, textPaddingV, textPaddingH, textPaddingV); //设置padding
  30. textView.setClickable(true);//设置textView可以被点击
  31. textView.setOnClickListener(new OnClickListener() { // 设置点击事件
  32. @Override
  33. public void onClick(View v) {
  34. Toast.makeText(UiUtils.getContext(), str, 0).show();
  35. }
  36. });
  37. layout.addView(textView,new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, -2));// -2 包裹内容
  38. }
  39. scrollView.addView(layout);
  40. return scrollView;
  41. }
  42. @Override
  43. protected LoadResult load() {
  44. TopProtocol protocol=new TopProtocol();
  45. datas = protocol.load(0);
  46. return checkData(datas);
  47. }
  48. }
到目前为止实现的效果是这样的,将LinearLayout使用一个自定义控件


Flowlayout 
原理

  1. public class Flowlayout extends ViewGroup {
  2. private int horizontolSpacing=UiUtils.dip2px(13);
  3. private int verticalSpacing=UiUtils.dip2px(13);
  4. public Flowlayout(Context context) {
  5. super(context);
  6. }
  7. public Flowlayout(Context context, AttributeSet attrs, int defStyle) {
  8. super(context, attrs, defStyle);
  9. }
  10. private Line currentline;// 当前的行
  11. private int useWidth=0;// 当前行使用的宽度
  12. private List<Line> mLines=new ArrayList<Flowlayout.Line>();
  13. private int width;
  14. public Flowlayout(Context context, AttributeSet attrs) {
  15. super(context, attrs);
  16. }
  17. // 测量 当前控件Flowlayout
  18. // 父类是有义务测量每个孩子的
  19. @Override
  20. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  21. // TODO Auto-generated method stub
  22. // MeasureSpec.EXACTLY;
  23. // MeasureSpec.AT_MOST;
  24. // MeasureSpec.UNSPECIFIED;
  25. mLines.clear();
  26. currentline=null;
  27. useWidth=0;
  28. int widthMode = MeasureSpec.getMode(widthMeasureSpec);
  29. int heightMode = MeasureSpec.getMode(heightMeasureSpec); // 获取当前父容器(Flowlayout)的模式
  30. width = MeasureSpec.getSize(widthMeasureSpec)-getPaddingLeft()-getPaddingRight();
  31. int height = MeasureSpec.getSize(heightMeasureSpec)-getPaddingBottom()-getPaddingTop(); // 获取到宽和高
  32. int childeWidthMode;
  33. int childeHeightMode;
  34. // 为了测量每个孩子 需要指定每个孩子测量规则
  35. childeWidthMode=(widthMode==MeasureSpec.EXACTLY)?MeasureSpec.AT_MOST:widthMode;
  36. childeHeightMode=heightMode==MeasureSpec.EXACTLY?MeasureSpec.AT_MOST:heightMode;
  37. int childWidthMeasureSpec=MeasureSpec.makeMeasureSpec(childeWidthMode, width);
  38. int childHeightMeasureSpec=MeasureSpec.makeMeasureSpec(childeHeightMode, height);
  39. currentline=new Line();// 创建了第一行
  40. for(int i=0;i<getChildCount();i++) {
  41. View child=getChildAt(i);
  42. System.out.println("孩子的数量:"+getChildCount());
  43. // 测量每个孩子
  44. child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
  45. int measuredWidth = child.getMeasuredWidth();
  46. useWidth+=measuredWidth;// 让当前行加上使用的长度
  47. if(useWidth<=width){
  48. currentline.addChild(child);//这时候证明当前的孩子是可以放进当前的行里,放进去
  49. useWidth+=horizontolSpacing;
  50. if(useWidth>width){
  51. //换行
  52. newLine();
  53. }
  54. }else{
  55. //换行
  56. if(currentline.getChildCount()<1){
  57. currentline.addChild(child); // 保证当前行里面最少有一个孩子
  58. }
  59. newLine();
  60. }
  61. }
  62. if(!mLines.contains(currentline)){
  63. mLines.add(currentline);// 添加最后一行
  64. }
  65. int totalheight=0;
  66. for(Line line:mLines){
  67. totalheight+=line.getHeight();
  68. }
  69. totalheight+=verticalSpacing*(mLines.size()-1)+getPaddingTop()+getPaddingBottom();
  70. System.out.println(totalheight);
  71. setMeasuredDimension(width+getPaddingLeft()+getPaddingRight(),resolveSize(totalheight, heightMeasureSpec));
  72. }
  73. private void newLine() {
  74. mLines.add(currentline);// 记录之前的行
  75. currentline=new Line(); // 创建新的一行
  76. useWidth=0;
  77. }
  78. private class Line{
  79. int height=0; //当前行的高度
  80. int lineWidth=0;
  81. private List<View> children=new ArrayList<View>();
  82. /**
  83. * 添加一个孩子
  84. * @param child
  85. */
  86. public void addChild(View child) {
  87. children.add(child);
  88. if(child.getMeasuredHeight()>height){
  89. height=child.getMeasuredHeight();
  90. }
  91. lineWidth+=child.getMeasuredWidth();
  92. }
  93. public int getHeight() {
  94. return height;
  95. }
  96. /**
  97. * 返回孩子的数量
  98. * @return
  99. */
  100. public int getChildCount() {
  101. return children.size();
  102. }
  103. public void layout(int l, int t) {
  104. lineWidth+=horizontolSpacing*(children.size()-1);
  105. int surplusChild=0;
  106. int surplus=width-lineWidth;
  107. if(surplus>0){
  108. surplusChild=surplus/children.size();
  109. }
  110. for(int i=0;i<children.size();i++){
  111. View child=children.get(i);
  112. // getMeasuredWidth() 控件实际的大小
  113. // getWidth() 控件显示的大小
  114. child.layout(l, t, l+child.getMeasuredWidth()+surplusChild, t+child.getMeasuredHeight());
  115. l+=child.getMeasuredWidth()+surplusChild;
  116. l+=horizontolSpacing;
  117. }
  118. }
  119. }
  120. // 分配每个孩子的位置
  121. @Override
  122. protected void onLayout(boolean changed, int l, int t, int r, int b) {
  123. l+=getPaddingLeft();
  124. t+=getPaddingTop();
  125. for(int i=0;i<mLines.size();i++){
  126. Line line=mLines.get(i);
  127. line.layout(l,t); //交给每一行去分配
  128. t+=line.getHeight()+verticalSpacing;
  129. }
  130. }
  131. }
如果不要平均分配那些步骤,实现的效果是这样的

 

自定义一个圆形的进度条
  1. public class ProgressView extends View {
  2. public ProgressView(Context context) {
  3. super(context);
  4. }
  5. public ProgressView(Context context, AttributeSet attrs, int defStyle) {
  6. super(context, attrs, defStyle);
  7. }
  8. public ProgressView(Context context, AttributeSet attrs) {
  9. super(context, attrs);
  10. }
  11. // 绘制控件
  12. @Override
  13. protected void onDraw(Canvas canvas) {
  14. super.onDraw(canvas);
  15. //canvas.drawBitmap(bitmap, left, top, paint);
  16. /*oval 圆的模型 矩形
  17. * startAngle 开始的角度
  18. * sweepAngle 范围的角度
  19. * useCenter 是否填充中间部分
  20. * paint 画笔
  21. */
  22. //canvas.drawArc(oval, startAngle, sweepAngle, useCenter, paint);
  23. }
  24. }





posted @ 2015-11-20 19:43  梦和远方  阅读(171)  评论(0编辑  收藏  举报