想知道哪些组件可以得到焦点可以查他们的父类 像View你看看API有没有设置焦点的接口 正好View里面有个属性android:focusable 所以所有继承View的都能获得焦点
基于Android9x
Window和Session创建成功后,窗口的下一步流程为获取焦点
我们看下焦点获取过程,跟输入法相关的流程
两个Activity切换时,对应的状态变化过程为:
以下是Activity窗口初次获取焦点的流程
当两个activity 切换时,失去焦点的窗口调用过程如下:
对应的,获取焦点的额窗口的调用过程如下:
当B窗口的状态切换到RESUMED时,当窗口的focus可能变化时,会调用updateFocusedWindowLocked
在该方法中,判断,如果还没有执行startInputInner方法,则执行startInputInner方法,否则,直接执行startInputOrWindowGainedFocus方法
主要流程:
1:设置controlFlags的flag为CONTROL_WINDOW_FIRST
2:检查是否已经执行过startInputInner,没有的话执行startInputInner-->startInputOrWindowGainedFocus;否则,直接执行startInputOrWindowGainedFocus
两条路径,携带的startInputReason参数不一样
主要流程:
1:检查要启动和退出的ServedView是否为同一个,如果为同一个,则表示已经执行过startInputInner,则返回false,表示不再执行startInputInner
2:如果获取焦点的是EditorText,会创建跟IMS通信的mServedInputConnectionWrapper对象
主要流程:
1:创建EditorInfo对象tba,这个参数对TextView布局才有意义,它的初始化是在mServedView的onCreateInputConnection完成实例化的
2:根据EditorInfo创建一个InputConnection对象,输入法应用通过该对象,完成输入内容到输入框的传递;ACTIVITY获取焦点场景,该对象
为null,因为没有要输入的对象
startInputOrWindowGainedFocus携带的参数
startInputReason = 1
表示,该流程是窗口获取焦点过程
mClient
应用层创建的IInputMethodClient对象,为服务层提供应用层的各个回调方法
该方法跟应用进程首次创建时Session时,传递到IMMS的对象是同一个对象
windowGainingFocus:
应用层的ViewRootImpl$W对象
controlFlags |= CONTROL_START_INITIAL;
表示window窗口刚开始获取焦点
softInputMode = SOFT_INPUT_ADJUST_RESIZE , 允许调整输入法窗口,避免被其他窗口遮挡
tba , EditorInfo对象
servedContext
null
missingMethodFlags
ic等于null的情况下,为0
当应用层传递的W对象windowToken不为null的时候,则创建windowGainedFocus对象,返回给app
结果返回后,会对IMM的对象进行赋值
如此,进入一个窗口,获取窗口焦点过程,窗口与输入法相关的流程,就结束了。
下一篇:输入法在输入框d出流程
Android输入法(3),d出流程
正常情况下在UITextView中系统会自动处理光标可见,然而实际开发中产品设计并不会局限于系统本身的空间,但作为开发者必须尽其所能的去实现,满足产品设计,达到最佳的用户体验,才能让产品有立足之地。
下面有一种情形可能是我们经常遇到的,如邮件的编辑界面。
该界面有如下控件
UITextField toTextField; // 收件人
UITextField ccTextField; // 抄送
UITextField subjectTextField; // 主题
UITextView contentTextView; // 内容
如果内容过多时,就显示不全,那么我们还必须加一个UIScrollView将上面的控件包着,支持上下滑动界面,以便查看所有内容
UIScrollView scrollView;
也许有人发现,textView本身是可以滑动的,而scrollView也可以滑动,这样会造成体验非常糟糕的结果。这种糟糕的体验起码我是决不能让其发生的,相信大家也是如此。
解决方案就是让textView的frame自适应其contentSize,然后再动态改变scrollview的contentSize,这样textview就不会独自滑动了。
上边的具体实现,相信大部分人都能知道。然后实现过的人又会遇到一个棘手的问题,内容过多时,光标不会自动向上移动,导致光标不见了。就是在这篇文章主要介绍的问题:“光标自动可见”
// 这里只介绍textview 自适应及光标自动可见的问题,所以其他的细节都省略。
#pragma mark -- KVO --
- (void)addContentView
{
contentTextView = [[UITextView alloc] initWithFrame:CGRectMake(0, 157, 3200f, 346)];
// 设置底部间距50,这个非常重要。不加的话,会出现异常的问题,可以自己动手试一试
contentTextViewcontentInset = UIEdgeInsetsMake(0, 0, 50, 0);
// 使用KVO 观察contentSize的动态
[contentTextView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
CGSize size = scrollViewframesize;
sizeheight = CGRectGetMaxY(contentTextViewframe);
scrollViewcontentSize = size;
[scrollView addSubview: contentTextView]
}
- (void)observeValueForKeyPath:(NSString )keyPath
ofObject:(id)object
change:(NSDictionary )change
context:(void )context
{
// 监听textview 的contensize是否改变
if ([keyPath isEqualToString:@"contentSize"])
{
UITextView view = object;
// 获取textView最新的contentSize的高度
CGFloat contentHeight = viewcontentSizeheight;
CGSize scrollViewContentSize = scrollViewcontentSize;
if (contentHeight > 346) { // 346 是textview的默认高度
CGRect frame = viewframe;
framesizeheight = contentHeight + 50; // 50 是底部间距
viewframe = frame;
scrollViewContentSizeheight = viewframeoriginy + viewframesizeheight;
}else {
scrollViewContentSizeheight = viewframeoriginy + viewframesizeheight - 14;
}
scrollViewcontentSize = scrollViewContentSize;
// 获取光标的位置区域
CGRect cursorPosition = [view caretRectForPosition:viewselectedTextRangestart];
// 光标相对顶层视图(scrollView)frame的坐标高度
CGFloat height = cursorPositionoriginy + viewframeoriginy - _mailScrollViewcontentOffsety;
//
CGFloat currentPoint = cursorPositionoriginy;
// 可见scrollView区域, 由于键盘有中英输入法,所以会导致可见区域的变化
CGFloat cursorValueMax = [UIScreen mainScreen]boundssizeheight - 64 - selfkeyboardkeyboardHeight;
if (height > cursorValueMax - 50) { // 当光标在可见区域底部50pix内,即距离键盘50pix内
[scrollView setContentOffset:CGPointMake(0, currentPoint + viewframeoriginy - cursorValueMax + 50) animated:YES];
} else if (height < 20) { // 当光标在可见区域顶部20pix内,即距离顶部20pix内
[scrollView scrollRectToVisible:CGRectMake(0, cursorPositionoriginy - 20, 320, 60) animated:YES];
}
}
}
这还不简单吗?直接加个动画就行了!
现在我做下补充:
package comqiulongtextscrolldemo;import androidcontentContext;
import androidgraphicsCanvas;
import androidgraphicsColor;
import androidgraphicsPaint;
import androidutilAttributeSet;
import androidviewView;
public class CustomScrollText extends View {
//背景画笔
private Paint backPaint;
//背景颜色
private int backColor = ColorGRAY;
//文本画笔
private Paint textPaint;
//字体颜色
private int textColor = ColorBLACK;
//字体大小
private int textSize = 20;
//文字内容
private String textContent = "textView";
//X轴偏移量
private float OffsetX = 0;
//刷新线程
private RefreshRunnable mRefreshRunnable;
public CustomScrollText(Context context) {
super(context);
init();
}
public CustomScrollText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomScrollText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
/
初始化画笔
/
private void init(){
backPaint = new Paint();
backPaintsetAntiAlias(true);
backPaintsetColor(backColor);
backPaintsetStyle(PaintStyleFILL);
textPaint = new Paint();
textPaintsetAntiAlias(true);
textPaintsetColor(textColor);
textPaintsetStyle(PaintStyleFILL);
textPaintsetTextSize(textSize);
}
@Override
protected void onAttachedToWindow() {
superonAttachedToWindow();
//启动刷新
mRefreshRunnable = new RefreshRunnable();
post(mRefreshRunnable);
}
@Override
protected void onDetachedFromWindow() {
superonDetachedFromWindow();
//关闭刷新
removeCallbacks(mRefreshRunnable);
}
@Override
protected void onDraw(Canvas canvas) {
superonDraw(canvas);
//绘制背景
canvasdrawRect(0, 0, getWidth(), textSize+10, backPaint);// 长方形
//绘制文本内容
canvasdrawText(textContent, OffsetX, textSize, textPaint);
}
/
测量控件宽高
/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measure(widthMeasureSpec);
int height = measure(heightMeasureSpec);
setMeasuredDimension(width, height);
}
private int measure(int measureSpec) {
int specMode = MeasureSpecgetMode(measureSpec);
int specSize = MeasureSpecgetSize(measureSpec);
int result = 70;
if (specMode == MeasureSpecAT_MOST) {//最大可获空间
result = specSize;
} else if (specMode == MeasureSpecEXACTLY) {//精确尺寸
result = specSize;
}
return result;
}
/
刷新线程
@author qiulong
/
private class RefreshRunnable implements Runnable {
public void run() {
synchronized (CustomScrollTextthis) {
OffsetX--;
//获取字体宽度
float txtWidth = textPaintmeasureText(textContent, 0, textContentlength());
if((0 - OffsetX) >= txtWidth){
OffsetX = getWidth();
}
invalidate();
postDelayed(this, 5);
}
}
}
/
设置文本内容
@param value
/
public void setTextContent(String value){
thistextContent = value;
}
/
获取文本内容
@return
/
public String getTextContent(){
return textContent;
}
/
设置文本颜色
@param color
/
public void setTextColor(int color){
thistextColor = color;
textPaintsetColor(textColor);
}
/
获取文本颜色
@return
/
public int getTextColor(){
return textColor;
}
/
设置文本大小
@param size
/
public void setTextSize(int size){
thistextSize = size;
textPaintsetTextSize(textSize);
}
/
获取文本大小
@return
/
public int getTextSize(){
return textSize;
}
/
设置背景颜色
/
public void setBackgroundColor(int color){
thisbackColor = color;
backPaintsetColor(backColor);
}
/
获取背景颜色
@return
/
public int getBackgroundColor(){
return backColor;
}
}
下面是MainActivityclass :
package comqiulongtextscrolldemo;import androidosBundle;
import androidappActivity;
import androidgraphicsColor;
public class MainActivity extends Activity {
private CustomScrollText mtext;
@Override
protected void onCreate(Bundle savedInstanceState) {
superonCreate(savedInstanceState);
setContentView(Rlayoutactivity_main);
mtext = (CustomScrollText)findViewById(Ridmtext);
mtextsetTextContent("你加个我看看,说谁都会说,你怎么不干脆说让他直接滚动起来就好了,回答问题也要有点诚意好不");
mtextsetTextSize(30);
mtextsetTextColor(ColorBLUE);
mtextsetBackgroundColor(ColorGREEN);
}
}
然后至于你说的速度控制方面,也很简单!你可以尝试修改下,我就不一五一十的全帮你写了!另外还有一个你说的信息间距我没搞懂是什么意思!
android系统的文本视图的意思。
TextView是android里面用的最多的控件,TextView类似一般UI中的Label,TextBlock等控件,只是为了单纯的显示一行或多行文本。TextView作为android开发中最简单也最常用的控件,作为初学者,需要熟知其属性并熟练掌握。
android:cursorVisible设定光标为显示/隐藏,默认显示。
android:digits设置允许输入哪些字符。如“1234567890+-/% ()”
android:drawableBottom在text的下方输出一个drawable,如。如果指定一个颜色的话会text的背景设为该颜色,并且同时和background使用时覆盖后者。
android:drawableLeft在text的左边输出一个drawable,如。
android:drawablePadding设置text与drawable()的间隔,与drawableLeft、 drawableRight、drawableTop、drawableBottom一起使用,可设置为负数,单独使用没有效果。
android:drawableRight在text的右边输出一个drawable。
android:drawableTop在text的正上方输出一个drawable。
android:editable设置是否可编辑。
android:editorExtras设置文本的额外的输入数据。
android:ellipsize设置当文字过长时,该控件该如何显示。有如下值设置:”start”—-省略号显示在开头;”end” ——省略号显示在结尾;”middle”—-省略号显示在中间;”marquee” ——以跑马灯的方式显示(动画横向移动)
android:freezesText设置保存文本的内容以及光标的位置。
android:gravity设置文本位置,如设置成“center”,文本将居中显示。
android:hintText为空时显示的文字提示信息,可通过textColorHint设置提示信息的颜色。此属性在 EditView中使用,但是这里也可以用。
android:imeOptions附加功能,设置右下角IME动作与编辑框相关的动作,如actionDone右下角将显示一个“完成”,而不设置默认是一个回车符号。这个在EditView中再详细说明,此处无用。
android:imeActionId设置IME动作ID。
android:imeActionLabel设置IME动作标签。
android:includeFontPadding设置文本是否包含顶部和底部额外空白,默认为true。
android:inputMethod为文本指定输入法,需要完全限定名(完整的包名)。
android:inputType设置文本的类型,用于帮助输入法显示合适的键盘类型。在EditView中再详细说明,这里无效果。
android:linksClickable设置链接是否点击连接,即使设置了autoLink。
android:marqueeRepeatLimit在ellipsize指定marquee的情况下,设置重复滚动的次数,当设置为 marquee_forever时表示无限次。
android:ems设置TextView的宽度为N个字符的宽度。这里测试为一个汉字字符宽度
android:maxEms设置TextView的宽度为最长为N个字符的宽度。与ems同时使用时覆盖ems选项。
android:minEms设置TextView的宽度为最短为N个字符的宽度。与ems同时使用时覆盖ems选项。
android:maxLength限制显示的文本长度,超出部分不显示。
android:lines设置文本的行数,设置两行就显示两行,即使第二行没有数据。
android:maxLines设置文本的最大显示行数,与width或者layout_width结合使用,超出部分自动换行,超出行数将不显示。
android:minLines设置文本的最小行数,与lines类似。
android:lineSpacingExtra设置行间距。
android:lineSpacingMultiplier设置行间距的倍数。如”12”
android:numeric如果被设置,该TextView有一个数字输入法。此处无用,设置后唯一效果是TextView有点击效果,此属性在EdtiView将详细说明。
android:password以小点””显示文本
android:phoneNumber设置为电话号码的输入方式。
android:privateImeOptions设置输入法选项,此处无用,在EditText将进一步讨论。
android:scrollHorizontally设置文本超出TextView的宽度的情况下,是否出现横拉条。
android:selectAllOnFocus如果文本是可选择的,让他获取焦点而不是将光标移动为文本的开始位置或者末尾位置。 TextView中设置后无效果。
android:shadowColor指定文本阴影的颜色,需要与shadowRadius一起使用。
android:shadowDx设置阴影横向坐标开始位置。
android:shadowDy设置阴影纵向坐标开始位置。
android:shadowRadius设置阴影的半径。设置为01就变成字体的颜色了,一般设置为30的效果比较好。
android:singleLine设置单行显示。如果和layout_width一起使用,当文本不能全部显示时,后面用“…”来表示。
android:singleLine="true" android:layout_width="20dp"将只显示“t…”。如果不设置singleLine或者设置为false,文本将自动换行
android:text设置显示文本
android:textAppearance设置文字外观。如 “android:attr/textAppearanceLargeInverse”这里引用的是系统自带的一个外观,表示系统是否有这种外观,否则使用默认的外观。可设置的值如下:textAppearanceButton/textAppearanceInverse/textAppearanceLarge/textAppearanceLargeInverse/textAppearanceMedium/textAppearanceMediumInverse/textAppearanceSmall/textAppearanceSmallInverse
android:textColor设置文本颜色
android:textColorHighlight被选中文字的底色,默认为蓝色
android:textColorHint设置提示信息文字的颜色,默认为灰色。与hint一起使用。
android:textColorLink文字链接的颜色
android:textScaleX设置文字之间间隔,默认为10f。
android:textSize设置文字大小,推荐度量单位”sp”,如”15sp”
android:textStyle设置字形[bold(粗体) 0, italic(斜体) 1, bolditalic(又粗又斜) 2] 可以设置一个或多个,用“|”隔开
android:typeface设置文本字体,必须是以下常量值之一:normal 0, sans 1, serif 2,
monospace(等宽字体) 3]
android:height设置文本区域的高度,支持度量单位:px(像素)/dp/sp/in/mm(毫米)
android:maxHeight设置文本区域的最大高度
android:minHeight设置文本区域的最小高度
android:width设置文本区域的宽度,支持度量单位:px(像素)/dp/sp/in/mm(毫米),与layout_width 的区别看这里
android:maxWidth设置文本区域的最大宽度
android:minWidth设置文本区域的最小宽度
以上就是关于Android:Android中组件获取焦点问题全部的内容,包括:Android:Android中组件获取焦点问题、Android 输入法窗口焦点获取流程(2) ,输入法窗口和应用窗口绑定、如何让UITextView光标一直处于焦点状态等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)