Android面试简录——组件
组件所在包:android.widget
组件的属性
- android:id属性是必须的吗?请解释一下该属性的作用。
android:id属性在XML文件中不一定要指定。
android:id的作用:
1. Java代码中创建组件对象时,再定义组件时需要指定android:id对象;
2. RelativeLayout中需要确定组件之间的相对位置,需要指定组件ID。
【拓展】android:id属性值
设置方法:
1.@id/属性值
,该属性已在R类中定义;
2.@+id/属性值
,该属性没有事先定义。【建议使用】
- android:padding和android:layout_margin的区别
android:padding用于设置组件内容距离边缘的距离。
android:layout_margin用于设置组件之间的间隔距离。
【个人发现】加了
layout_
这个属性就是设置组件与组件级别的,没加就是设置组件内级别的。(如果有例外的话请告诉我=。=)
【拓展】分别设置上、下、左、右4个方向的间隔距离
1.android:padding
和android:layout_margin
会同时设置上下左右的距离。
2.android:paddingTop
,android:paddingBottom
,android:paddingLeft
,android:paddingRight
分别设置组件内上下左右的间隔距离。
3.android:layout_marginTop
,android:layout_mrginBottom
,android:layout_marginLeft
,android:layout_marginRight
分别设置组件间上下左右的间隔距离。
-
请简单描述一下android:gravity和android:layout_gravity属性的区别。
android:gravity用来设置组件内容相对于组件的相对位置。
android:layout_gravity用来设置组件在父组件中的相对位置。 -
请说出android:layout_weight属性的功能。
设置当前组件在水平或者垂直方向上所占空间的大小,属性值与当前组件的宽度和高度成反比。
文本组件
- 请简要说出Android SDK支持哪些方式显示富文本信息,并简要说明实现方法。
1.在TextView组件中使用富文本标签显示富文本信息。如<font>,<b>等。
【注意】包含这些标签的文本不能直接作为TextView.setText方法的参数值,而要先使用Html.fromHtml方法将这些文本转换成CharSequnence对象。
2.使用WebView显示HTML页面。
3.继承View或其子类,覆盖onDraw方法,在该方法中直接绘制富文本或图像。
4.上面3种方法都支持图片混排效果。
【注意】方法1在显示图像时需要实现ImageGetter接口,并通过ImageGetter.getDrawable方法返回封装图像资源的Drawable对象。
5.TextView组件中显示图像可以使用ImageSpan对象。
ImageSpan对象封装Bitmap对象 -> SpannableString对象封装ImageSpan对象 -> TextView.setText(SpannableString对象)。
【拓展】 在TextView中显示图像的办法
- 使用
<img>
标签
CharSequence charSequence = Html.fromHtml(html, new ImageGetter() {
@Override
public Drawable getDrawable(String source) {
Drawable drawable = getResources().getDrawable(getResourceId(source));
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
return drawable;
}
}, null);
textView.setText(charSequence); - 使用
ImageSpan
对象
Bitmap bitmap = BitmapFacttory.decodeResource(getResources(), R.drawable.icon);
ImageSpan imageSpan = new ImageSpan(this, bitmap);
SpannableString spannableString = new SpannableString("icon");
spannableString.setSpan(imageSpan, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
-
如何使用TextView组件单击链接后弹出自定义的Activity?
考查android.text.style包中Span对象的用法
URLSpan对象:可以使单击URL后立刻弹出浏览器来显示相应的界面。
ClickableSpan类:自定义单击URL链接动作String text = "显示Activity" SpannableString spannableString = new SpannableString(text); spannableString.setSpan(new ClickableSpan() { @Override public void onClick(View widgt) { Intent intent = new Intent(Main.this, Activity.class); startActivity(intent); } }, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setMovementMethod(LinkMovementMethod.getInstance());
【拓展】在EditText组件中插入表情图像?
只需要将以上在使用TextView对象插入富文本改为使用EditText对象即可。
-
如何为TextView组件中显示的文本添加背景色?
使用BackgroundColorSpan对象设置文字背景色。
TextView textView = (TextView) findViewById(R.id.textView);
String text = "带颜色的文本";
SpannableString spannableString = new SpannableString(text);
int start = 0;
int end = 7;
BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.getSpan(backgroundColorSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString); -
在设计电子词典程序时,当用户输入单词时,应显示当前输入单词的开头的单词列表。Android SDK中那个组件可以实现这个功能,请写出核心实现代码。
关键点:AutoCompleteTextView组件+数据库与该组件结合使用
TextWatcher.afterTextChanged:存放获取以某些字符开头的单词列表的代码块public void afterTextChanged(Editable s) { Cursor cursor = database.rawQuery( "select english as _id from t_words where english like ?", new String[] {s.toString() + "%"}); DictionaryAdapter dictionaryAdapter = new DictionaryAdapter(this, cursor, true); autoCompleteTextView.setAdapter(dictionaryAdapter); }
按钮组件
-
在按钮上显示图像的方法有哪些?
Button是TextView的子类 -> Button也可以实现图片混排的效果。
1. Button
a. android:drawableXxx(Xxx:Left/Top/Right/Bottom):将图像显示在文字的周围
b. ImageSpan封装Bitmap对象 -> SpannableString.setSpan方法设置ImageSpan对象 -> Button.setText/Button.append设置SpannableString对象
2. ImageButton
使用android:src属性指定图像文件的资源ID
3. RadioButton
和Button一样的设置方法 -
如何用代码动态改变Button的大小和位置?
Button是View的子类,可以使用Button.layout方法动态改变Button的大小和位置。
Button.layout:4个参数——左上角顶点和右下角顶点坐标。 -
怎样让一个显示图像的按钮在不同状态显示不同的图像?
drawable资源实现或者Java代码实现。这里主要说一下drawable资源实现的方法。
在drawable目录下新建xml文件,然后设置Button:background属性指向该xml文件即可。
xml文件如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="@drawable/pressed"
/>
<item
android:state_focused="true"
android:drawable="@drawable/focused"
/>
<item
android:drawable="@drawable/normal"
/>
</selector>
【拓展】drawable资源
drawable资源可以存储普通的图像资源,还可以存储XML图像资源:
1.图像状态资源:如上
2.淡入淡出资源:如下
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/lamp_off"/>
<item android:drawable="@drawable/lamp_on"/>
</transition>
3.图像级别资源:如下
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/lamp_off"
android:minLevel="6"
android:maxLevel="10"
/>
<item
android:drawable="@drawable/lamp_on"
android:minLevel="12"
android:maxLevel="20"
/>
</level-list>
在Java文件中使用setImageLevel或setLevel设置级别在某个区间,系统就会先使用那个区间的图像。
图像组件
-
如何实现图片的半透明度?
1.Paint.setAlpha。
Bitmap对象装载图像 -> View.onDraw(){Canvas.drawBitmap将Bitmap对象绘制在当前View上}
2.使用<FrameLayout>标签通过图层的方式实现图像的半透明效果。
在不透明的图像上覆盖一层半透明的膜
具体代码:
方法一:
InputStream is = getResources().openRawResource(R.drawable.image);
Bitmap bitmap = BitmapFactory.decodeStream(is);
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setAlpha(180);
canvas.drawBitmap(bitmap, new Rect(0, 0, bitmap.getWidth(),
bitmap.getHeight()), new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()),
paint);
}
方法二:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/image" />
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#EFFF" />
</FrameLayout> -
如何在ImageView组件中显示图像的一部分?
1.直接截取图像
2.图像剪切资源(只能从图像的一端开始截取,没有方法1灵活)
具体代码:
方法一:
Bitmap smallBitmap = Bitmap.createBitmap(sourceBitmap, 20, 20, 100, 100);
imageView.setImageBitmap(smallBitmap);
方法二:
1.在res/drawable目录中建立xml文件
<? xml version="1.0" encoding="utf-8" ?>
<clip xmlns:android="http://schema.android.com/apk/res/android"
android:drawable="@drawable/android"
android:clipOrientation="horizontal"
android:gravity="left" />
</clip>
2.在Java代码中使用ClipDrawable.setLevel设置截取的百分比
ImageView imageView = (ImageView) findViewById(R.id.image);
ClipDrawable drawable = (ClipDrawable) imageView.getDrawable();
drawable.setLevel(3000); //从图像左侧(因为在xml文件中设置了"horizontal"属性)截取图像的30% -
如何使用Matrix对象旋转和缩放图像?
1.Matrix.setRotate~旋转图像
Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.dog)).getBitmap();
Matrix matrix = new Matrix();
matrix.setRotate(45);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
imageView.setImageBitmap(bitmap);
2.Matrix.setScale~缩放图像
...
matrix.setScale((float)0.5, (float)0.5);
...
进度组件
- ProgressBar的进度条是否可以修改?
改变ProgressBar的进度条颜色(背景颜色,第一级进度条颜色,第二级进度条颜色)。
修改方案:使用图层列表(layer-list)资源修改颜色。
res/drawable中新建progressbar.xml文件:
<? xml version="1.0" encoding="utf-8" ?>
<layer-list xmlns:android="http://schema.android.com/apk/res/android" >
<item
android:id="@android:id/background"
android:drawable="@drawable/bg" />
<item
android:id="@android:id/secondaryProgress"
android:drawable="@drawable/secondary" />
<item
android:id="@android:id/progress"
android:drawable="@drawable/progress" />
</layer-list>
在<ProgressBar>标签中使用android:progressDrawable指定以上资源ID。
【拓展】实现更绚丽的进度条
layer-list
和Shape
资源结合,实现更绚丽的进度条。
设置圆角和渐变色效果:
<? xml version="1.0" encoding="utf-8" ?>
<layer-list xmlns:android="http://schema.android.com/apk/res/android" >
<item android:id="@android:id/background" >
<shape>
<corners android:radius="10dp" />
<gradient
android:startColor="#FFFF0000"
android:centerColor="#FF880000"
android:centerY="0.75"
android:endColor="#FF110000"
android:angle="270" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress" >
<clip>
<shape>
<corners android:radius="10dp" />
<gradient
android:startColor="#FF00FF00"
android:centerColor="#FF00FF00"
android:centerY="0.75"
android:endColor="FF00FF00"
android:angle="270" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress" >
<clip>
<shape>
<corner android:radius="10dp" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="270" />
</shape>
</clip>
</item>
</layer-list>
- 如何实现垂直进度条?
Android SDK没有提供垂直进度条组件。
使用图像剪切资源。
<? xml version="1.0" encoding="utf-8" ?>
<clip xmlns:android="http://schema.android.com/apk/res/android"
android:drawable="@drawable/android"
android:clipOrientation="vertical"
android:gravity="left" />
</clip>
Java代码:
ImageView imageView = (ImageView) findViewById(R.id.image);
ClipDrawable drawable = (ClipDrawable) imageView.getDrawable();
drawable.setLevel(3000);
列表组件
-
如何使用BaseAdapter的子类将数据显示在ListView组件中?
BaseAdapter的抽象方法:
1.getItem ~ 返回与当前列表项相关的Object对象,可不编写
2.getItemId ~ 返回列表项的ID,long类型的值,可不编写
3.getCount ~ 返回列表数据的总数,必须编写
4.getView ~ 返回在当前列表项显示的View对象,必须编写
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) { //没有View对象可以利用,必须创建新的View对象
convertView = layoutInflater.inflate(R.layout.list_item, null);
}
return convertView;
} -
如何对GridView,ListView等列表组件中的数据进行增、删、改、查操作?
列表组件采用MVC格式,必须在修改数据后使用notifyDataSetInvalidated方法通知列表组件#刷新#数据。 -
如何在ListView组件中显示数据库中的数据?
简单数据:SimpleCursorAdapter
复杂数据:编写继承CursorAdapter的类 -> 在newView方法中创建新的列表项View对象 -> 在bindView中卫相应的组件赋值。 -
如何改变ListView的背景色?
1.采用<listView>标签的android:listSelector属性
2.使用ListView.setSelector -
如果要做一个文件管理器,使用GridView组件显示文件列表,有的文件需要显示缩略图,应如何优化显示过程?
使用任务队列技术。
在getView方法中要显示某个图像文件的缩略图,可以先将该任务添加到任务队列中,然后使用另外一个线程不断扫描任务队列,并处理未完成的任务。当处理完某个任务后,可以刷新GridView组建来显示该图像文件的缩略图。当然,网络数据也可以采用这种方式进行优化。
具体步骤:使用数组/List对象建立任务队列和数据缓冲 -> 将getView中比较耗时的操作加入到该队列中 -> 另外一个线程执行任务队列中的任务 -> BaseAdapter.notifyDataSetChanged刷新列表数据。
代码如下:
public class ScanTaskThread extends Thread {
public void run() {
try {
//扫描任务队列以获取并处理任务
... ...
Thread.sleep(100);
} catch (Exception e) {} } }
-
如何为ListView组件加上加速滑块?
android:fastScrollEnabled属性设为true -> Java代码中调用ListView.setFastEnabled(true)方法。
ListView组建没有提供修改快速滑块图像的API,不能直接修改快速滑块图像,可以通过反射技术修改快速滑块图像:
Field field = AbsListView.class.getDeclaredField("mFastScroller");
field.setAccessible(true);
Object obj = field.get(listView);
field = field.getType().getDeclaredField("mThumbDrawable");
field.setAccessible(true);
Drawable drawable = (Drawable) field.get(obj);
drawable = getResources().getDrawable(R.drawable.image);
field.set(obj, drawable);
容器组件
- Android SDK支持的容器组件?
ViewGroup的子类都是容器组件。
五大布局组件,GridView,Gallery,ListView。 - 如何使容器内的组件可以水平和垂直滑动?
将ScrollView和HorizontalScrollView结合使用:
在<ScrollView>标签中使用<HorizontalScrollView>标签,或者相反。 - 如何使Gallery循环显示图像?
使BaseAdapter.getCount返回一个较大的值,当BaseAdapter.getView方法中不能通过position参数获得数据的位置,需要将position参数值对n(数组长度)取余,并将余数作为新的数据位置。
【后记】组件真的是太多了...下个文记述自定义组件和四大应用程序组件。