android自己定义控件系列教程----视图
理解android视图
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY29kZWJvYg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
android怎样控制视图的显示位置
/**
* Set the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the x position to scroll to
* @param y the y position to scroll to
*/
public void scrollTo(int x, int y) {
if (mScrollX != x || mScrollY != y) {
int oldX = mScrollX;
int oldY = mScrollY;
mScrollX = x;
mScrollY = y;
invalidateParentCaches();
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (!awakenScrollBars()) {
postInvalidateOnAnimation();
}
}
}
另一个是
/**
* Move the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the amount of pixels to scroll by horizontally
* @param y the amount of pixels to scroll by vertically
*/
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
我们细致的来解读一下上面的函数。这个源代码我是摘自5.0的源代码。
我们看到ScrollBy这个函数也是调用的ScrollTo我们就来分析一下ScrollTo这个函数究竟做了什么工作?非常easy的几句代码,最重要的一句就是这一句 postInvalidateOnAnimation();这一句代码会去回调我们的ondraw函数,在ondraw函数里面绘制我们的可见区域,然后我们在来看看VIew的draw的方法
* Manually render this view (and all of its children) to the given Canvas.
* The view must have already done a full layout before this function is
* called. When implementing a view, implement
* {@link #onDraw(android.graphics.Canvas)} instead of overriding this method.
* If you do need to override this method, call the superclass version.
*
* @param canvas The Canvas to which the View is rendered.
*/
public void draw(Canvas canvas) {
if (mClipBounds != null) {
canvas.clipRect(mClipBounds);
}
final int privateFlags = mPrivateFlags;
final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
(mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN; /*
* Draw traversal performs several drawing steps which must be executed
* in the appropriate order:
*
* 1. Draw the background
* 2. If necessary, save the canvas' layers to prepare for fading
* 3. Draw view's content
* 4. Draw children
* 5. If necessary, draw the fading edges and restore layers
* 6. Draw decorations (scrollbars for instance)
*/ // Step 1, draw the background, if needed
int saveCount; if (!dirtyOpaque) {
final Drawable background = mBackground;
if (background != null) {
final int scrollX = mScrollX;
final int scrollY = mScrollY; if (mBackgroundSizeChanged) {
background.setBounds(0, 0, mRight - mLeft, mBottom - mTop);
mBackgroundSizeChanged = false;
} if ((scrollX | scrollY) == 0) {
background.draw(canvas);
} else {
canvas.translate(scrollX, scrollY);
background.draw(canvas);
canvas.translate(-scrollX, -scrollY);
}
}
} // skip step 2 & 5 if possible (common case)
final int viewFlags = mViewFlags;
boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
if (!verticalEdges && !horizontalEdges) {
// Step 3, draw the content
if (!dirtyOpaque) onDraw(canvas); // Step 4, draw the children
dispatchDraw(canvas); // Step 6, draw decorations (scrollbars)
onDrawScrollBars(canvas); if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().dispatchDraw(canvas);
} // we're done...
return;
} /*
* Here we do the full fledged routine...
* (this is an uncommon case where speed matters less,
* this is why we repeat some of the tests that have been
* done above)
*/ boolean drawTop = false;
boolean drawBottom = false;
boolean drawLeft = false;
boolean drawRight = false; float topFadeStrength = 0.0f;
float bottomFadeStrength = 0.0f;
float leftFadeStrength = 0.0f;
float rightFadeStrength = 0.0f; // Step 2, save the canvas' layers
int paddingLeft = mPaddingLeft; final boolean offsetRequired = isPaddingOffsetRequired();
if (offsetRequired) {
paddingLeft += getLeftPaddingOffset();
} int left = mScrollX + paddingLeft;
int right = left + mRight - mLeft - mPaddingRight - paddingLeft;
int top = mScrollY + getFadeTop(offsetRequired);
int bottom = top + getFadeHeight(offsetRequired); if (offsetRequired) {
right += getRightPaddingOffset();
bottom += getBottomPaddingOffset();
} final ScrollabilityCache scrollabilityCache = mScrollCache;
final float fadeHeight = scrollabilityCache.fadingEdgeLength;
int length = (int) fadeHeight; // clip the fade length if top and bottom fades overlap
// overlapping fades produce odd-looking artifacts
if (verticalEdges && (top + length > bottom - length)) {
length = (bottom - top) / 2;
} // also clip horizontal fades if necessary
if (horizontalEdges && (left + length > right - length)) {
length = (right - left) / 2;
} if (verticalEdges) {
topFadeStrength = Math.max(0.0f, Math.min(1.0f, getTopFadingEdgeStrength()));
drawTop = topFadeStrength * fadeHeight > 1.0f;
bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, getBottomFadingEdgeStrength()));
drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
} if (horizontalEdges) {
leftFadeStrength = Math.max(0.0f, Math.min(1.0f, getLeftFadingEdgeStrength()));
drawLeft = leftFadeStrength * fadeHeight > 1.0f;
rightFadeStrength = Math.max(0.0f, Math.min(1.0f, getRightFadingEdgeStrength()));
drawRight = rightFadeStrength * fadeHeight > 1.0f;
} saveCount = canvas.getSaveCount(); int solidColor = getSolidColor();
if (solidColor == 0) {
final int flags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG; if (drawTop) {
canvas.saveLayer(left, top, right, top + length, null, flags);
} if (drawBottom) {
canvas.saveLayer(left, bottom - length, right, bottom, null, flags);
} if (drawLeft) {
canvas.saveLayer(left, top, left + length, bottom, null, flags);
} if (drawRight) {
canvas.saveLayer(right - length, top, right, bottom, null, flags);
}
} else {
scrollabilityCache.setFadeColor(solidColor);
} // Step 3, draw the content
if (!dirtyOpaque) onDraw(canvas); // Step 4, draw the children
dispatchDraw(canvas); // Step 5, draw the fade effect and restore layers
final Paint p = scrollabilityCache.paint;
final Matrix matrix = scrollabilityCache.matrix;
final Shader fade = scrollabilityCache.shader; if (drawTop) {
matrix.setScale(1, fadeHeight * topFadeStrength);
matrix.postTranslate(left, top);
fade.setLocalMatrix(matrix);
canvas.drawRect(left, top, right, top + length, p);
} if (drawBottom) {
matrix.setScale(1, fadeHeight * bottomFadeStrength);
matrix.postRotate(180);
matrix.postTranslate(left, bottom);
fade.setLocalMatrix(matrix);
canvas.drawRect(left, bottom - length, right, bottom, p);
} if (drawLeft) {
matrix.setScale(1, fadeHeight * leftFadeStrength);
matrix.postRotate(-90);
matrix.postTranslate(left, top);
fade.setLocalMatrix(matrix);
canvas.drawRect(left, top, left + length, bottom, p);
} if (drawRight) {
matrix.setScale(1, fadeHeight * rightFadeStrength);
matrix.postRotate(90);
matrix.postTranslate(right, top);
fade.setLocalMatrix(matrix);
canvas.drawRect(right - length, top, right, bottom, p);
} canvas.restoreToCount(saveCount); // Step 6, draw decorations (scrollbars)
onDrawScrollBars(canvas); if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().dispatchDraw(canvas);
}
}
能够看到取出我们的mScrollX和mScrollY然后在画图的各种translate画图这样我们就看到了视图里面显示的内容了。大体上的思路就是这样。
显示区域实例
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setLayoutParams(new LayoutParams(2000, 2000));//这里我把宽高设置大点好做測试由于我的手机是1920*1080所以设置得大一点
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
TextView textView1 = new TextView(this);
textView1.setText("hello i am text 1");
textView1.setLayoutParams(new LayoutParams(1000, 2000));
linearLayout.addView(textView1);
TextView textView2 = new TextView(this);
textView2.setText("hello i am text 2");
textView2.setLayoutParams(new LayoutParams(1000, 2000));
linearLayout.addView(textView2);
setContentView(linearLayout);
我们给它一个非常大的视图,大得都超出了手机屏幕,然后我们跑一下看会有如何的效果。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY29kZWJvYg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setLayoutParams(new LayoutParams(2000, 2000));//这里我把宽高设置大点好做測试由于我的手机是1920*1080所以设置得大一点
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
TextView textView1 = new TextView(this);
textView1.setText("hello i am text 1");
textView1.setLayoutParams(new LayoutParams(1000, 2000));
linearLayout.addView(textView1);
TextView textView2 = new TextView(this);
textView2.setText("hello i am text 2");
textView2.setLayoutParams(new LayoutParams(1000, 2000));
linearLayout.addView(textView2);
linearLayout.scrollTo(1000, 0);//我们加了这一句代码
setContentView(linearLayout);
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY29kZWJvYg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
android自己定义控件系列教程----视图的更多相关文章
- android自己定义控件系列教程-----仿新版优酷评论剧集卡片滑动控件
我们先来看看优酷的控件是怎么回事? 仅仅响应最后也就是最顶部的卡片的点击事件,假设点击的不是最顶部的卡片那么就先把它放到最顶部.然后在移动到最前面来.重复如次. 知道了这几条那么我们就非常好做了. 里 ...
- Android自己定义控件系列五:自己定义绚丽水波纹效果
尊重原创!转载请注明出处:http://blog.csdn.net/cyp331203/article/details/41114551 今天我们来利用Android自己定义控件实现一个比較有趣的效果 ...
- Android自己定义控件系列二:自己定义开关button(一)
这一次我们将会实现一个完整纯粹的自己定义控件,而不是像之前的组合控件一样.拿系统的控件来实现.计划分为三部分:自己定义控件的基本部分,自己定义控件的触摸事件的处理和自己定义控件的自己定义属性: 以下就 ...
- Android自己定义控件系列案例【五】
案例效果: 案例分析: 在开发银行相关client的时候或者开发在线支付相关client的时候常常要求用户绑定银行卡,当中银行卡号一般须要空格分隔显示.最常见的就是每4位数以空格进行分隔.以方便用户实 ...
- Android自己定义控件系列三:自己定义开关button(二)
接上一篇自己定义开关button(一)的内容继续.上一次实现了一个开关button的基本功能.即自己定义了一个控件.开关button,实现了点击切换开关状态的功能.今天我们想在此基础之上.进一步实现触 ...
- Android自己定义控件系列一:Android怎样实现老版优酷client三级环形菜单
转载请附上本文链接:http://blog.csdn.net/cyp331203/article/details/40423727 先来看看效果: 一眼看上去好像还挺炫的,感觉比較复杂...实际上并不 ...
- Android自己定义控件:进度条的四种实现方式
前三种实现方式代码出自: http://stormzhang.com/openandroid/2013/11/15/android-custom-loading/ (源代码下载)http://down ...
- android 自己定义控件
Android自己定义View实现非常easy 继承View,重写构造函数.onDraw.(onMeasure)等函数. 假设自己定义的View须要有自己定义的属性.须要在values下建立attrs ...
- Android自己定义控件皮肤
Android自己定义控件皮肤 对于Android的自带控件,其外观仅仅能说中规中矩,而我们平时所示Android应用中,一个简单的button都做得十分美观.甚至于很多button在按下时的外观都有 ...
随机推荐
- C# 设置系统环境变量
using Microsoft.Win32; using System; using System.Collections.Generic; using System.ComponentModel; ...
- windows sdk 设置窗体透明
#define WINVER 0x0501 #include <windows.h> /* Declare Windows procedure */ LRESULT CALLBACK Wi ...
- ssd遇到的bug
从训练一开始就loss为0: 最开始以为是在生成train.lmdb前没有对label_map进行修改,发现并不是这个问题 1.训练的命令是:python ./examples/ssd/ssd_pas ...
- java_线程分类
线程分为守护线程和用户线程,如java虚拟机的回收机制就是守护线程,线程开始运行它就启动,线程结束它就结束 用户线程变守护线程:Thread(线程).setDaemon(true)
- qrcode.js扫码邀请
//js引用部分<script src="../qrcode.js" type="text/javascript"></script> ...
- struts2与常用表格ajax操作的json传值问题
struts与常用的dataTables和jqueryGrid等表格进行ajax传值时,经常会传值不适配的问题,这是因为struts在进行ajax操作时已经对你要操作的json数据进行了处理,所以不需 ...
- 集训第六周 数学概念与方法 UVA 11181 条件概率
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18546 题意:有n个人会去超市,其中只有r个人会买东西,每个人独自买东西的概 ...
- web环境搭建
[服务器] 硬件设备---计算机 软件 [作用] 作为web服务器运行.可以管理web项目 [目录说明] bin :存放各类可以执行文件,如:startup.bat conf:存放各类配置文件,常用配 ...
- loadrunner-3个难点
1.loadrunner 监控windows资源 2.loadrunner如何实现如下: 1.1.1.1 场景一 10进程同时新增用户 测试场景说明:10进程新增用户, 第一个进程从1到1000,第二 ...
- centos6.4下安装mysql
一.mysql简介 说到数据库,我们大多想到的是关系型数据库,比如mysql.oracle.sqlserver等等,这些数据库软件在windows上安装都非常的方便,在Linux上如果要安装数据库,咱 ...