Android面试简录——组件

作者: nancymi | 来源:发表于2015-04-03 16:30 被阅读1213次

    组件所在包: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:paddingandroid: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中显示图像的办法

    1. 使用<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);
    2. 使用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-listShape资源结合,实现更绚丽的进度条。
    设置圆角和渐变色效果:

      <? 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(数组长度)取余,并将余数作为新的数据位置。

    【后记】组件真的是太多了...下个文记述自定义组件和四大应用程序组件。

    相关文章

      网友评论

      • SG_0_O:关于id属性值,还有一种是代码中创建的View控件,调用view.setId(int id) 方法,id可以是代码中自定义的Int 常量。

      本文标题:Android面试简录——组件

      本文链接:https://www.haomeiwen.com/subject/kaioxttx.html