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

来自为知笔记(Wiz)

时间: 2024-10-24 15:07:52

15.瀑布流、测量的相关文章

瀑布流ListView

前言 终于忙完了一段时间,现在前段时间写的一个瀑布流ListView到想法分享下,这个东西是扩展自Listview,当列表内容拉到最后后触发刷新操作,以便抓取更多到数据. 先贴下整个代码,先有个整体到概念,然后再进一步细聊.代码如下 1 package cn.bitlove.waterfalllistview.widget; 2 3 import cn.bitlove.waterfalllistview.R; 4 import android.content.Context; 5 import

iOS开发笔记15:地图坐标转换那些事、block引用循环、UICollectionviewLayout及瀑布流、图层混合

1.地图坐标转换那些事 (1)投影坐标系与地理坐标系 地理坐标系使用三维球面来定义地球上的位置,单位即经纬度.但经纬度无法精确测量距离戒面积,也难以在平面地图戒计算机屏幕上显示数据.通过投影的方式可以将其转换成平面的投影坐标系,不同的投影方式可能会带来不同的变形及误差,类似于把一个橘子的橘子皮剥开摊平到桌面. GPS以及iOS系统定位获得的坐标是地理坐标系WGS1984,Web地图一般用的坐标细是投影坐标系WGS 1984 Web Mercator,国内出于相关法律法规要求,对国内所有GPS设备

IOS 瀑布流UICollectionView实现

IOS 瀑布流UICollectionView实现 在实现瀑布流之前先来看看瀑布流的雏形(此方法的雏形 UICollectionView) 对于UICollectionView我们有几点注意事项 它和tableView不一样,ContentView的内容完全需要我们自己去添加. 它与tableview相比,他的初始化需要FlowLayout并且大部分操作在其上. UIcollectionView的实用性极强,虽然有时他并不是最好的解决方案,但是它可以很灵活的实现各种效果. 图(一) 如图,模拟器

自定义控件三部曲视图篇(三)——瀑布流容器WaterFallLayout实现

前言:只要在前行,梦想就不再遥远 系列文章: Android自定义控件三部曲文章索引:http://blog.csdn.net/harvic880925/article/details/50995268 前面两节讲解了有关ViewGroup的onMeasure.onLayout的知识,这节我们深入性地探讨一下,如何实现经常见到的瀑布流容器,本节将实现的效果图如下: 从效果图中可以看出这里要完成的几个功能: 1.图片随机添加 2.在添加图片时,总是将新图片插入到当前最短的列中 3.每个Item后,

js实现瀑布流以及加载效果

一.瀑布流是个啥? 瀑布流,是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部. 最早采用瀑布流布局的网站是Pinterest,逐渐在国内流行开来,比如我们熟知的百度图片的布局,在"很久"以前,百度图片还是需要一页一页的点击进行查看更多图片,而现在的瀑布流布局使用户查找图片更加方便. 二.瀑布流的优缺点 优点: 1.节省了页面的空间,不再需要导航和页码按钮. 2.增强了用户的体验,使用户的体验更多的是在于浏览图

jQuery瀑布流插件——jQuery.Waterfall

插件--jQuery.Waterfall 思路: 其实只要了解了整个流程,要实现这个插件也不难,大家都玩过俄罗斯方块吧,原理差不多,找到合适的地方叠上去就好了,在这里,每个块的宽度是必需给定的,然后计算出列数,再维护一个数组,存储每列的高度,往最小高度的列添加块即可.滚动时,当最小高度出现在可视窗口时就启动ajax从服务器拉取更多的数据. 注意的地方: 如果瀑布流的块中包含图片,则需要事先知道图片的高度(其实就是为了要计算出整个块的高度,以便精确定位),图片的高度可以从服务器返回,本插件是整合p

js瀑布流(定位法)

1.首先,自己写好图片路径,引入jquery <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> *{ padding: 0; margin: 0; } ul{ position: relative; width: 860px; margin: 0

js 瀑布流

项目没上线,办公室里坐着学习技术,尼玛钱不够花啊,所以多学技术呗,仿写了个js 瀑布流,ide用的是idea14. 效果还可以. 1.项目效果图 index.html <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>js瀑布流</title> <link href="css/app.css

面向对象js瀑布流效果

index.html <!doctype html><html lang="en"> <head>  <!--网站编码格式,UTF-8 国际编码,GBK或 gb2312 中文编码-->  <meta charset="UTF-8">  <meta name="Keywords" content="">  <meta name="Descri