編輯:關於Android編程
實現原理:頂部利用了ListView的HeadView來實現,然後其他每個item都用背景實現!
首先設置一些常量:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PHByZSBjbGFzcz0="brush:java;">package com.cyy.widget;
/**
* @see http://blog.csdn.net/chenlove1
* @author chenyingyou
*
*/
public class NestHelper {
public static final int BACK_COLOR = 0xFFF8F3D5;// 背景色
public static final int LINE_COLOR = 0xFF5A595A;// 線顏色
public static final int LINE_WIDTH = 2;// 線的寬度(要偶數)
public static final int LINE_SPAN = 4;// 線的間距
}
每個item的背景實現最為核心,請看代碼:
package com.cyy.widget; import android.content.Context; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.widget.FrameLayout; /** * @see http://blog.csdn.net/chenlove1 * @author chenyingyou * */ public class NestItemLayout extends FrameLayout implements NestNotifyData { public NestItemLayout(Context context) { super(context); } public NestItemLayout(Context context, AttributeSet attrs) { super(context, attrs); } public NestItemLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @SuppressWarnings("deprecation") @Override public void notifyDataSetChanged(int count, int position) { setBackgroundDrawable(new NestDrawable(count, position)); } /** 繪制item Layout背景 兩邊跟底部 */ class NestDrawable extends Drawable { private int linsCount = 0;// 兩邊各有多少條線 private int span = 0;// 一條線的寬度(線加線之間距) public NestDrawable(int count, int position) { linsCount = count - position; if (linsCount > 5) { linsCount = 5;// 一邊最多5條 } span = (NestHelper.LINE_WIDTH + NestHelper.LINE_SPAN); setPadding(span * linsCount, 0, span * linsCount, NestHelper.LINE_WIDTH); } @Override public void draw(Canvas canvas) { canvas.drawColor(NestHelper.BACK_COLOR); Paint paint = new Paint(); paint.setColor(NestHelper.LINE_COLOR); paint.setStrokeWidth(NestHelper.LINE_WIDTH); // 繪制底部線 canvas.drawLine(span * (linsCount - 1), getHeight() - NestHelper.LINE_WIDTH / 2, getWidth() - span * (linsCount - 1), getHeight() - NestHelper.LINE_WIDTH / 2, paint); for (int i = 0; i < linsCount; i++) { // 繪制左邊線 canvas.drawLine(span * i + NestHelper.LINE_WIDTH / 2, 0, span * i + NestHelper.LINE_WIDTH / 2, getHeight(), paint); // 繪制右邊線 canvas.drawLine(getWidth() - span * i - NestHelper.LINE_WIDTH / 2, 0, getWidth() - span * i - NestHelper.LINE_WIDTH / 2, getHeight(), paint); ; } } @Override public void setAlpha(int alpha) { } @Override public void setColorFilter(ColorFilter cf) { } @Override public int getOpacity() { return 0; } } }
package com.cyy.widget; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; import android.widget.AbsListView; import android.widget.AbsListView.LayoutParams; /** * @see http://blog.csdn.net/chenlove1 * @author chenyingyou * */ public class NestHeadView extends View implements NestNotifyData { private int linsCount = 0;// 狀況要繪制多少條線 private int span = 0;// 一條線的寬度(線加線之間距) public NestHeadView(Context context) { super(context); } public NestHeadView(Context context, AttributeSet attrs) { super(context, attrs); } public NestHeadView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(NestHelper.BACK_COLOR); Paint paint = new Paint(); paint.setColor(NestHelper.LINE_COLOR); paint.setStrokeWidth(NestHelper.LINE_WIDTH); for (int i = 0; i < linsCount; i++) { // 繪制左邊線 canvas.drawLine(span * i + NestHelper.LINE_WIDTH / 2, span * i, span * i + NestHelper.LINE_WIDTH / 2, getHeight(), paint); // 繪制右邊線 canvas.drawLine(getWidth() - span * i - NestHelper.LINE_WIDTH / 2, span * i, getWidth() - span * i - NestHelper.LINE_WIDTH / 2, getHeight(), paint); // 繪制底部線 canvas.drawLine(span * (linsCount - 1 - i), getHeight() - span * i - NestHelper.LINE_WIDTH / 2, getWidth() - span * (linsCount - 1 - i), getHeight() - span * i - NestHelper.LINE_WIDTH / 2, paint); } } @Override public void notifyDataSetChanged(int count, int position) { linsCount = count - position; if (linsCount > 5) { linsCount = 5;// 一邊最多5條 } span = (NestHelper.LINE_WIDTH + NestHelper.LINE_SPAN); setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT, span * (linsCount - 1) + NestHelper.LINE_WIDTH)); invalidate(); } }最後重寫ListView:
package com.cyy.widget; import android.content.Context; import android.util.AttributeSet; import android.widget.ListView; /** * @see http://blog.csdn.net/chenlove1 * @author chenyingyou * */ public class NestListView extends ListView implements NestNotifyData { private NestHeadView headView; public NestListView(Context context) { super(context); initView(); } public NestListView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public NestListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(); } private void initView() { headView = new NestHeadView(getContext()); addHeaderView(headView); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } @Override public void notifyDataSetChanged(int count, int position) { headView.notifyDataSetChanged(count, position); } public NestNotifyData getNotifyData() { return this; } }
背景:其實,關於實現機器人聊天,是偶然的情況下的,公司需要做一個ios版的機器人,用於自動購買東西,然後ios就研發了一個,我覺得這種機器人挺好玩的,想明白到底怎麼實現,
(/device/console操控台原理分析,通過調用此操控台來輸出信息,同時這兒涉及到/device/console調用TTY,然後TTY調用低層串口的分析 安桌LO
通過上一節的分析,我們發現InputDispatcherThread使用InputChannel的sendMessage方法發送了一條消息,但是我們不知道誰在接收這條消息
Android開發中經常使用Handler來實現“跨越線程(Activity)更新UI”。本文將從源碼角度回答:為什麼使用Handler能夠跨線程更新UI?為什麼跨線程更