15.瀑布流、测量
排行界面
TopProtocol?:json數據就是寫字符串,所以不需要寫bean對象public class TopProtocol extends BaseProtocol<List<String>> { @Override public List<String> paserJson(String json) { List<String> datas=new ArrayList<String>(); try { JSONArray array=new JSONArray(json); for(int i=0;i<array.length();i++){ String str=array.getString(i); datas.add(str); } return datas; } catch (JSONException e) { e.printStackTrace(); return null; } } @Override public String getKey() { return "hot"; } } DrawableUtils?:用代碼創建狀態選擇器 和圓角public class DrawableUtils { public static GradientDrawable createShape(int color){ GradientDrawable drawable=new GradientDrawable();//相當于shape drawable.setCornerRadius(UiUtils.dip2px(5));//設置4個角的弧度 drawable.setColor(color);// 設置顏色 return drawable; } public static StateListDrawable createSelectorDrawable(Drawable pressedDrawable,Drawable normalDrawable){ // <selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="200"> // <item android:state_pressed="true" android:drawable="@drawable/detail_btn_pressed"></item> // <item android:drawable="@drawable/detail_btn_normal"></item> // </selector> StateListDrawable stateListDrawable=new StateListDrawable(); stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, pressedDrawable);// 按下顯示的圖片 stateListDrawable.addState(new int[]{}, normalDrawable);// 抬起顯示的圖片 return stateListDrawable; } } TopFragment?:使用代碼創建、隨機色MATCH_PARENT?、FILL_PARENT是-1且他倆個沒有任何區別,WRAP_CONTENT是-2?public class TopFragment extends BaseFragment { private List<String> datas; @Override public View createSuccessView() { ScrollView scrollView=new ScrollView(UiUtils.getContext()); scrollView.setBackgroundResource(R.drawable.grid_item_bg_normal); LinearLayout layout=new LinearLayout(UiUtils.getContext()); int padding=UiUtils.dip2px(13); layout.setPadding(padding, padding, padding, padding); layout.setOrientation(LinearLayout.VERTICAL);// 設置線性布局的方向 int backColor = 0xffcecece; Drawable pressedDrawable=DrawableUtils.createShape(backColor);// 按下顯示的圖片 for(int i=0;i<datas.size();i++){ TextView textView=new TextView(UiUtils.getContext()); final String str=datas.get(i); textView.setText(str); Random random=new Random(); //創建隨機 int red = random.nextInt(200)+22; int green = random.nextInt(200)+22; int blue = random.nextInt(200)+22;//有可能都是0或255成白色或者黑色了 int color=Color.rgb(red, green, blue);//范圍 0-255 GradientDrawable createShape = DrawableUtils.createShape(color); // 默認顯示的圖片 StateListDrawable createSelectorDrawable = DrawableUtils.createSelectorDrawable(pressedDrawable, createShape);// 創建狀態選擇器 textView.setBackgroundDrawable(createSelectorDrawable); textView.setTextColor(Color.WHITE); //textView.setTextSize(UiUtils.dip2px(14)); int textPaddingV = UiUtils.dip2px(4); int textPaddingH = UiUtils.dip2px(7); textView.setPadding(textPaddingH, textPaddingV, textPaddingH, textPaddingV); //設置padding textView.setClickable(true);//設置textView可以被點擊 textView.setOnClickListener(new OnClickListener() { // 設置點擊事件 @Override public void onClick(View v) { Toast.makeText(UiUtils.getContext(), str, 0).show(); } }); layout.addView(textView,new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, -2));// -2 包裹內容 } scrollView.addView(layout); return scrollView; } @Override protected LoadResult load() { TopProtocol protocol=new TopProtocol(); datas = protocol.load(0); return checkData(datas); } } 到目前為止實現的效果是這樣的,將LinearLayout使用一個自定義控件
Flowlayout?原理
public class Flowlayout extends ViewGroup { private int horizontolSpacing=UiUtils.dip2px(13); private int verticalSpacing=UiUtils.dip2px(13); public Flowlayout(Context context) { super(context); } public Flowlayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } private Line currentline;// 當前的行 private int useWidth=0;// 當前行使用的寬度 private List<Line> mLines=new ArrayList<Flowlayout.Line>(); private int width; public Flowlayout(Context context, AttributeSet attrs) { super(context, attrs); } // 測量 當前控件Flowlayout // 父類是有義務測量每個孩子的 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub // MeasureSpec.EXACTLY; // MeasureSpec.AT_MOST; // MeasureSpec.UNSPECIFIED; mLines.clear(); currentline=null; useWidth=0; int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); // 獲取當前父容器(Flowlayout)的模式 width = MeasureSpec.getSize(widthMeasureSpec)-getPaddingLeft()-getPaddingRight(); int height = MeasureSpec.getSize(heightMeasureSpec)-getPaddingBottom()-getPaddingTop(); // 獲取到寬和高 int childeWidthMode; int childeHeightMode; // 為了測量每個孩子 需要指定每個孩子測量規則 childeWidthMode=(widthMode==MeasureSpec.EXACTLY)?MeasureSpec.AT_MOST:widthMode; childeHeightMode=heightMode==MeasureSpec.EXACTLY?MeasureSpec.AT_MOST:heightMode; int childWidthMeasureSpec=MeasureSpec.makeMeasureSpec(childeWidthMode, width); int childHeightMeasureSpec=MeasureSpec.makeMeasureSpec(childeHeightMode, height); currentline=new Line();// 創建了第一行 for(int i=0;i<getChildCount();i++) { View child=getChildAt(i); System.out.println("孩子的數量:"+getChildCount()); // 測量每個孩子 child.measure(childWidthMeasureSpec, childHeightMeasureSpec); int measuredWidth = child.getMeasuredWidth(); useWidth+=measuredWidth;// 讓當前行加上使用的長度 if(useWidth<=width){ currentline.addChild(child);//這時候證明當前的孩子是可以放進當前的行里,放進去 useWidth+=horizontolSpacing; if(useWidth>width){ //換行 newLine(); } }else{ //換行 if(currentline.getChildCount()<1){ currentline.addChild(child); // 保證當前行里面最少有一個孩子 } newLine(); } } if(!mLines.contains(currentline)){ mLines.add(currentline);// 添加最后一行 } int totalheight=0; for(Line line:mLines){ totalheight+=line.getHeight(); } totalheight+=verticalSpacing*(mLines.size()-1)+getPaddingTop()+getPaddingBottom(); System.out.println(totalheight); setMeasuredDimension(width+getPaddingLeft()+getPaddingRight(),resolveSize(totalheight, heightMeasureSpec)); } private void newLine() { mLines.add(currentline);// 記錄之前的行 currentline=new Line(); // 創建新的一行 useWidth=0; } private class Line{ int height=0; //當前行的高度 int lineWidth=0; private List<View> children=new ArrayList<View>(); /** * 添加一個孩子 * @param child */ public void addChild(View child) { children.add(child); if(child.getMeasuredHeight()>height){ height=child.getMeasuredHeight(); } lineWidth+=child.getMeasuredWidth(); } public int getHeight() { return height; } /** * 返回孩子的數量 * @return */ public int getChildCount() { return children.size(); } public void layout(int l, int t) { lineWidth+=horizontolSpacing*(children.size()-1); int surplusChild=0; int surplus=width-lineWidth; if(surplus>0){ surplusChild=surplus/children.size(); } for(int i=0;i<children.size();i++){ View child=children.get(i); // getMeasuredWidth() 控件實際的大小 // getWidth() 控件顯示的大小 child.layout(l, t, l+child.getMeasuredWidth()+surplusChild, t+child.getMeasuredHeight()); l+=child.getMeasuredWidth()+surplusChild; l+=horizontolSpacing; } } } // 分配每個孩子的位置 @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { l+=getPaddingLeft(); t+=getPaddingTop(); for(int i=0;i<mLines.size();i++){ Line line=mLines.get(i); line.layout(l,t); //交給每一行去分配 t+=line.getHeight()+verticalSpacing; } } } 如果不要平均分配那些步驟,實現的效果是這樣的
自定義一個圓形的進度條public class ProgressView extends View { public ProgressView(Context context) { super(context); } public ProgressView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public ProgressView(Context context, AttributeSet attrs) { super(context, attrs); } // 繪制控件 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //canvas.drawBitmap(bitmap, left, top, paint); /*oval 圓的模型 矩形 * startAngle 開始的角度 * sweepAngle 范圍的角度 * useCenter 是否填充中間部分 * paint 畫筆 */ //canvas.drawArc(oval, startAngle, sweepAngle, useCenter, paint); } }
來自為知筆記(Wiz)
TopProtocol?:json數據就是寫字符串,所以不需要寫bean對象
Flowlayout?原理
自定義一個圓形的進度條
來自為知筆記(Wiz)
轉載于:https://www.cnblogs.com/sixrain/p/4982185.html
總結
- 上一篇: 郑州银行信用卡申请条件有哪些?需要准备什
- 下一篇: 郑州银行信用卡好申请吗?申请进度怎么查询