当前位置: 代码迷 >> Android >> Android自定义带题目边框的Layout
  详细解决方案

Android自定义带题目边框的Layout

热度:10   发布时间:2016-04-28 08:00:35.0
Android自定义带标题边框的Layout

     今天工作中又碰到个小问题,项目需要用到像Java Swing的JPanel一样带标题边框的布局,Android里没有类似控件,想到这个也不难,自己画了一个,是继承LinearLayout的一个自定义布局,当然,可以根据需要继承其他布局,基本都是一样的过程。

      当然这个自定义布局有点瑕疵,就是标题占用了布局的一部分高度,子控件需要调整在布局中的垂直位置来避免和标题边框靠得过紧。


------------------本博客如未明正声明转载,皆为原创,转载请注明出处!------------------


下面贴代码:

/** * 一个像java swing的JPanel控件一样可以带标题边框的布局,可以指定标题位置、颜色、字体大小。 * 另外还可以控制边框大小和边框的颜色。但是,子控件指定垂直布局适应的时候,子控件看起来并不在布局中间, * 因为标题高度占用了布局的一部分垂直空间,使用时子控件需要指定Margin Top,否则可能和标题重叠。 *  * This is a layout with title border, you can set a title just like Java-Swing JPanel. * and you can control the position, the color and the size of the title. In addition, * the border's color and size are always controlled. *  * !FIXME: The title has its own height, so when the children's gravity set as [email protected] Gravity#CENTER}  * or [email protected] Gravity#CENTER_VERTICAL} do not work well. *  * @date 2013/09/24 * @author Wison */public class TitleBorderLayout extends LinearLayout {		/**  默认情况下标题在总长度的1/10处显示  */	private static float DEFAULT_TITLE_POSITION_SCALE = 0.1f;	public static int DEFAULT_BORDER_SIZE = 1;	public static int DEFAULT_BORDER_COLOR = Color.GRAY;	public static int DEAFULT_TITLE_COLOR = Color.BLACK;	/** 边框面板的高度 */	private int mBorderPaneHeight ;		private Paint mBorderPaint;	private float mBorderSize;		private TextPaint mTextPaint;	private CharSequence mTitle;	private int mTitlePosition;		public TitleBorderLayout(Context context) {		this(context, null);	}		/**	 * Construct a new TitleBorderLayout with default style, overriding specific style     * attributes as requested.	 * @param context	 * @param attrs	 */	public TitleBorderLayout(Context context, AttributeSet attrs) {		super(context, attrs);		setWillNotDraw(false);				mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);		mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);		Resources res = getResources();		mTextPaint.density = res.getDisplayMetrics().density;				TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TitleBorderLayout);				mTitle = a.getText(R.styleable.TitleBorderLayout_title);		int titleColor = a.getColor(R.styleable.TitleBorderLayout_titleTextColor, DEAFULT_TITLE_COLOR);		mTextPaint.setColor(titleColor);				float titleTextSize = a.getDimension(R.styleable.TitleBorderLayout_titleTextSize, 0);		if (titleTextSize > 0) {			mTextPaint.setTextSize(titleTextSize);		}				mTitlePosition = a.getDimensionPixelSize(R.styleable.TitleBorderLayout_titlePosition, -1);		mBorderSize = a.getDimensionPixelSize(R.styleable.TitleBorderLayout_borderSize, DEFAULT_BORDER_SIZE);				int borderColor = a.getColor(R.styleable.TitleBorderLayout_borderColor, DEFAULT_BORDER_COLOR);		mBorderPaint.setColor(borderColor);				a.recycle();	}		/**	 * Get the color of border.	 * @return	 */	public int getBorderColor() {		return mBorderPaint.getColor();	}	/**	 * Set the color of border.	 * @param borderColor	 */	public void setBorderColor(int borderColor) {		mBorderPaint.setColor(borderColor);		requestLayout();	}	/**	 * Get the size of border.	 * @return	 */	public float getBorderSize() {		return mBorderSize;	}	/**	 * Set the size of border.	 * @param borderSize	 */	public void setBorderSize(float borderSize) {		mBorderSize = borderSize;		requestLayout();	}	/**	 * Get the color of title.	 * @return	 */	public int getTitleColor() {		return mTextPaint.getColor();	}	/**	 * Set the color of title.	 * @param titleColor	 */	public void setTitleColor(int titleColor) {		mTextPaint.setColor(titleColor);		requestLayout();	}	/**	 * Get the size of title.	 * @return	 */	public float getTitleTextSize() {		return mTextPaint.getTextSize();	}	/**	 * Set the size of title.	 * @param titleTextSize	 */	public void setTitleTextSize(float titleTextSize) {		mTextPaint.setTextSize(titleTextSize);		requestLayout();	}		/**	 * Get the title.	 * @return	 */	public CharSequence getTitle() {		return mTitle;	}	/**	 * Set the title which will be shown on the top of border pane. 	 * @param title	 */	public void setTitle(CharSequence title) {		mTitle = title;		requestLayout();	}		/**	 * Get the position of title.	 * @return	 */	public int getTitlePosition() {		return mTitlePosition;	}	/**	 * Set the position of title where the paint will start to draw.	 * @param titlePosition	 */	public void setTitlePosition(int titlePosition) {		mTitlePosition = titlePosition;		requestLayout();	}	/**	 * Get the height of border pane, it's different from the layout height!	 * @return	 */	public int getBorderPaneHeight() {		return mBorderPaneHeight;	}	/**	 * Draw the title border	 * @param canvas 	 */	@Override	protected void onDraw(Canvas canvas) {		super.onDraw(canvas);				FontMetrics fm = mTextPaint.getFontMetrics();		final float titleHeight =  fm.descent - fm.ascent;		final CharSequence titleText = (mTitle == null) ? "" : mTitle;		final float titleWidth = Layout.getDesiredWidth(titleText, mTextPaint);				final int width = getWidth();		final int height = getHeight();				if (mTitlePosition <= 0 || mTitlePosition + titleWidth > width) {			mTitlePosition = (int) (DEFAULT_TITLE_POSITION_SCALE * width); 		}				final float topBorderStartY = titleHeight / 3f - mBorderSize / 2;				mBorderPaneHeight = (int) Math.ceil(height - topBorderStartY);	    /*  画标题边框  */		// 上		canvas.drawRect(0, topBorderStartY, mTitlePosition, topBorderStartY + mBorderSize, mBorderPaint);		canvas.drawText(titleText.toString(), mTitlePosition, titleHeight / 3 * 2f, mTextPaint); // 标题		canvas.drawRect(mTitlePosition + titleWidth, topBorderStartY, width, topBorderStartY + mBorderSize, mBorderPaint);        // 左        canvas.drawRect(0, topBorderStartY, mBorderSize, height, mBorderPaint);        // 右        canvas.drawRect(width - mBorderSize, topBorderStartY, width, height, mBorderPaint);        // 下        canvas.drawRect(0, height - mBorderSize, width, height, mBorderPaint);	}	}


以下为属性声明:

    <declare-styleable name="TitleBorderLayout">        <!-- The title of BorderTitleLayout. -->        <attr name="title" format="string" />        <!-- The size of title. -->        <attr name="titleTextSize" format="dimension" />        <!-- The title start postion. -->        <attr name="titlePosition" format="dimension" />        <!-- The color of title. -->        <attr name="titleTextColor" format="reference|color" />        <!-- The size of border. -->        <attr name="borderSize" format="dimension" />        <!-- The color of border. -->        <attr name="borderColor" format="reference|color" />    </declare-styleable>

下面是效果图:



  相关解决方案