谷歌电子市场第5天知识总结

一.按照宽高比例显示图片

1.

/**设置专题的图片大小比例,都是一样的比例宽高*/
public class RationLayout extends FrameLayout{

	public RationLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public RationLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
//		TypedArray typearray = context.obtainStyledAttributes(attrs, R.styleable.Ratiolayout);
//		float ratio = typearray.getFloat(R.styleable.Ratiolayout_ratio, 0f);
//		typearray.recycle();//保持一致
		float ratio = attrs.getAttributeFloatValue("http://schemas.android.com/apk/res/com.example.play", "ratio", 0f);
		setRatio(ratio);
	}

	private void setRatio(float ratio) {
		this.rotio = ratio ;
	}

	public RationLayout(Context context) {
		super(context);
	}

	float rotio;//比例
	private int width;
	private int height;
	//父容器(ViewGroup的测量规则)
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		
		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		width = widthSize - getPaddingLeft() - getPaddingRight();
		
		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		int heighSize = MeasureSpec.getSize(heightMeasureSpec);
		height = heighSize - getPaddingTop() - getPaddingBottom();
		
		//如果宽是精确的高不是,就按照宽来制定高
		if(widthMode==MeasureSpec.EXACTLY&&heightMode!=MeasureSpec.EXACTLY){
			height = (int) (width / rotio + 0.5f);
			
		//如果高是精确的宽不是,就按照高来制定宽
		}else if(widthMode!=MeasureSpec.EXACTLY&&heightMode==MeasureSpec.EXACTLY){
			width = (int) (height * rotio + 0.5f);
		}
		
		//重新制定一个测量规则
		widthMeasureSpec = MeasureSpec.makeMeasureSpec(
				MeasureSpec.EXACTLY,width + getPaddingLeft() +getPaddingRight());
		heightMeasureSpec = MeasureSpec.makeMeasureSpec(
				MeasureSpec.EXACTLY,height + getPaddingTop() +getPaddingBottom());
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}
}


xml文件

<com.example.play.view.RationLayout
            android:id="@+id/fl_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            gan:ratio="2.43"
            android:padding="5dp" >

            <ImageView
                android:id="@+id/item_icon"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:scaleType="fitCenter"
                android:src="@drawable/ic_default" />
        </com.example.play.view.RationLayout>

2.自定义属性,设置比例

①.设置attrs下的xml

<resources>

  <declare-styleable name="Ratiolayout">//设置集合名字
        <attr name="ratio" format="float" />//设置特定的属性名字
    </declare-styleable>

</resources>
②.获取属性

public RationLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
<span style="white-space:pre">		</span>//第一种方式,这种最佳,可以解析 id的国际化设置
//		TypedArray typearray = context.obtainStyledAttributes(attrs, R.styleable.Ratiolayout);//根据集合名字获取集合
//		float ratio = typearray.getFloat(R.styleable.Ratiolayout_ratio, 0f);//根据特定名字获取该属性
//		typearray.recycle();//保持一致

<span style="white-space:pre">		</span>//第2中方式.通过xml中的命名空间  和  属性名字  获取属性
		float ratio = attrs.getAttributeFloatValue("http://schemas.android.com/apk/res/com.example.play", "ratio", 0f);
		setRatio(ratio);
	}

3.xml中设置ratio属性的值

 xmlns:gan="http://schemas.android.com/apk/res/com.example.play"

        <com.example.play.view.RationLayout
            android:id="@+id/fl_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            gan:ratio="2.43"
            android:padding="5dp" ><!-- 设置自定义属性 -->

二.代码设置排行页面的布局




1.自定义线性布局添加textView ,设置textVIew的选择器


@Override
	protected View createSuccessView() {
		ScrollView scrollView = new ScrollView(BaseApplication.getApplication());
		//LinearLayout linearLayout = new LinearLayout(BaseApplication.getApplication());
		FlowLayout linearLayout = new FlowLayout(BaseApplication.getApplication());
		int padding = Uiutils.dip2px(13);
		linearLayout.setPadding(padding, padding, padding, padding);
		//linearLayout.setOrientation(LinearLayout.VERTICAL);//设置线性排列
		//-----------------------因为需要根据网络读取有多少字段,所以代码设置TextView
		for (int i = 0; i < data.size(); i++) {
			final String des = data.get(i);
			
			//文字设置
			TextView textView = new TextView(BaseApplication.getApplication());
			textView.setText(data.get(i));
			textView.setTextColor(Color.WHITE);
			
			//随机颜色
			Random random = new Random();
			int red = random.nextInt(200)+20;
			int green = random.nextInt(200)+20;
			int blue = random.nextInt(200)+20;
			int color = Color.rgb(red, green, blue);
			
			//设置选择器
			int backColor = 0xffcecece;
			GradientDrawable pressDrawable = GradientUtils.getGradientDrawable(backColor);//按下的图片
			GradientDrawable defaultDrawable = GradientUtils.getGradientDrawable(color);//默认的图片
			
			//状态选择器
			textView.setBackgroundDrawable(GradientUtils.getStateListDrawable(pressDrawable, defaultDrawable));
			
			//设置边距
			int PaddingL = Uiutils.dip2px(4);
			int PaddingH = Uiutils.dip2px(7);
			textView.setPadding(PaddingH, PaddingL, PaddingH, PaddingL);//给textView设置padding距离父亲
			textView.setClickable(true);
			textView.setGravity(Gravity.CENTER);
			//点击事件
			textView.setOnClickListener( new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					Toast.makeText(BaseApplication.getApplication(), des, 0).show();
				}
			});
			//设置textView包裹内容
			linearLayout.addView(textView,new LayoutParams(LayoutParams.WRAP_CONTENT, -2));
		}
		scrollView.addView(linearLayout);
		return scrollView;
	}


2.设置布局,一个线性布局根据textView的大小填充

public class FlowLayout extends ViewGroup {

	public FlowLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public FlowLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public FlowLayout(Context context) {
		super(context);
		init();
	}

	private void init() {

	}

	// Viewgroup必须实现的方法。因为要对孩子分配位置
	// 怎么分配位置?----1.对孩子进行测量
	// ----2.然后才进行分配位置
	//

	/** 1.对孩子进行测量 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		lines.clear();
		currentLine = null;

		// ------------父亲FlowLayout的大小和模式
		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		
		width = MeasureSpec.getSize(widthMeasureSpec)-getPaddingLeft()-getPaddingRight();// 宽
		height = MeasureSpec.getSize(heightMeasureSpec)-getPaddingTop()-getPaddingBottom();// 高

		// ------------根据父亲的模式获得孩子的测量规则
		int childWidthMode;
		int childHeightMode;
		// 模式
		childWidthMode = (widthMode == MeasureSpec.EXACTLY ? MeasureSpec.AT_MOST
				: widthMode);
		childHeightMode = (heightMode == MeasureSpec.EXACTLY ? MeasureSpec.AT_MOST
				: heightMode);
		// 测量规则
		int childwidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidthMode,width);
		int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeightMode, height);
		// 测量
		currentLine = new Line();// 创建一个新行
		for (int i = 0; i < getChildCount(); i++) {
			View child = getChildAt(i);
			getChildAt(i)
					.measure(childwidthMeasureSpec, childheightMeasureSpec);
			int textViewWidth = child.getMeasuredWidth();// 获得textView的高度
			useWidth = useWidth + textViewWidth;// 加到使用的里面去
			if (useWidth > width) {
				if (currentLine.getChildCount() < 1) {
					currentLine.addLine(child);
				}
				newLine();// 如果使用的行的宽度>行宽,换行

			} else { // 否则添加TextView到这个行里面
				currentLine.addLine(child);
				useWidth = useWidth + horizontalSpace;// 加上间隔
				if (useWidth > width) {
					newLine();// 如果加了间隔大于行宽,换行
				}
			}
		}
		if (!lines.contains(currentLine)) {// 添加最后一行
			lines.add(currentLine);
		}
		// 行的总高度
		int totalheight = 0;
		for (Line line : lines) {
			totalheight += line.getheight();// 获取所有行的高
		}
		totalheight += (lines.size() - 1) * verticalSpace+getPaddingBottom()+getPaddingTop();// 加上行的间隔
		
		// 按照自己的宽高去设置
		setMeasuredDimension(width+getPaddingLeft()+getPaddingRight(), resolveSize(totalheight, heightMeasureSpec));
	}

	/** 2.分配位置 */
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		l = l +getPaddingLeft();
		t= t +getPaddingTop();
		for (int i = 0; i < lines.size(); i++) {// 分配每行
			Line line = lines.get(i);
			line.layout(l, t);// 让孩子自己去做
			t += line.getheight() + verticalSpace;// 行高 + 间隔
		}
	}

	private List<Line> lines = new ArrayList<Line>();// 所有行的集合
	private Line currentLine;// 当前行
	private int useWidth = 0;// 使用的行的宽度
	private int horizontalSpace = Uiutils.dip2px(13);
	private int verticalSpace =  Uiutils.dip2px(13);
	private int width;
	private int height;

	class Line {
		private List<View> children = new ArrayList<View>();
		private int height;// 行高就等于孩子的高
		int lineWidth;// 孩子的宽的和
		private int surplusWidth = 0;// 一行剩余的宽度

		// 添加一个孩子
		public void addLine(View child) {

			if (child.getMeasuredHeight() > height) {// 如果下一个高度大于上一个的高度,就按照大的来
				height = child.getMeasuredHeight();
			}
			children.add(child);
			lineWidth += child.getMeasuredWidth();
		}

		// 该行的TextView的个数
		public int getChildCount() {
			return children.size();
		}

		// 分配孩子的位置
		public void layout(int l, int t) {
			int aveWidth = 0;
			lineWidth += horizontalSpace * (children.size() - 1);// 加上间隔的和
			surplusWidth = width - lineWidth;// 剩余的空间
			if (surplusWidth > 0) {
				if (children.size() > 0) {
					aveWidth = surplusWidth / (children.size());
				}
			}
			for (int i = 0; i < children.size(); i++) {
				View child = children.get(i);
				// 分配每个孩子的位置
				child.layout(l, t, l + child.getMeasuredWidth()+ aveWidth,
						t + child.getMeasuredHeight());
				l += child.getMeasuredWidth()+ aveWidth;
				l += horizontalSpace ;
				// t += child.getMeasuredHeight()*i;
			}
		}

		// 获得行的高度
		public int getheight() {
			return height;
		}

	}

	/** 换行 */
	private void newLine() {
		lines.add(currentLine);
		currentLine = new Line();// 重新建立一个当前行对象
		useWidth = 0;// 使用的行的宽设为0;
	}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值