展会信息港展会大全

android教程 在ListView中实现顶部和底部内容指示器
来源:互联网   发布日期:2015-11-26 10:20:38   浏览:3100次  

导读:顶部指示器?这是什么?好吧,我承认这是我自己想出来的词,因为我不知道它有什么学名,究竟是什么呢?看下这个图就知道了。这是我们的美工MM画的,偶的神呐,这虽然很漂亮,不过也让人头疼,这个箭头应该在滚到顶......

顶部指示器?

这是什么?

好吧,我承认这是我自己想出来的词,因为我不知道它有什么学名,究竟是什么呢?看下这个图就知道了。

这是我们的美工MM画的,偶的神呐,这虽然很漂亮,不过也让人头疼,这个箭头应该在滚到顶部的时候消失,滚下来的时候(即有条目隐藏的时候)才显示,类似的底部指示器也要有这样的效果。事实上默认的ListView和ScrollView都已经有了类似的效果,在顶部或底部还有更多内容时,会有部分渐变虚化的效果,不过美工已经设计了这样的效果,那么我们就来做吧。

出于省事的目的,本教程中的例子会基于上一篇教程来修改,主要是添加1个继承自ListView的类,以及修改布局定义文件。

ArrowListView控件的编写

package net.learningandroid.lib.view;

import net.learningandroid.lib.R;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.Rect;

import android.graphics.drawable.BitmapDrawable;

import android.util.AttributeSet;

import android.util.Log;

import android.view.View;

import android.widget.ListView;

/**

* 支持上下箭头的ListView

*

* @author Mr. Lu

*/

public class ArrowListView extends ListView {

private final float scale = getContext().getResources().getDisplayMetrics().density;

private float topArrowPadding;

private float bottomArrowPadding;

private static float DEFAULT_TOP_PADDING_DP = 2.0f;

private static float DEFAULT_BOTTOM_PADDING_DP = 2.0f;

public ArrowListView(Context context, AttributeSet attrs) {

super(context, attrs);

String strTopArrowPadding = attrs.getAttributeValue(null,

"topArrowPadding");

String strBottomArrowPadding = attrs.getAttributeValue(null,

"bottomArrowPadding");

topArrowPadding = convertDisplayUom(strTopArrowPadding,

DEFAULT_TOP_PADDING_DP);

bottomArrowPadding = convertDisplayUom(strBottomArrowPadding,

DEFAULT_BOTTOM_PADDING_DP);

Log.v("ArrowListView", String.valueOf(topArrowPadding));

}

/**

* 单位转换

*/

private float convertDisplayUom(String sour, float defaultValue) {

try {

if (sour.toLowerCase().endsWith("px")) {

return Float.parseFloat(sour.toLowerCase().replace("px", ""));

} else if (sour.toLowerCase().endsWith("dp")) {

return Integer.parseInt(sour.toLowerCase().replace("dp",

""))

* scale + 0.5f;

}

} catch (Exception e) {

}

return (defaultValue * scale + 0.5f);

}

/**

* onDraw方法,根据ListView滚动位置绘出箭头.

*/

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

Paint paint = new Paint();

// 取得箭头的图片,此处是固定图片,其实上可以做成配置方式

Bitmap topPic = ((BitmapDrawable) getResources().getDrawable(

R.drawable.arrow_up)).getBitmap();

Bitmap bottomPic = ((BitmapDrawable) getResources().getDrawable(

R.drawable.arrow_down)).getBitmap();

// 取得ListView的绘制区域大小

Rect r = new Rect();

this.getDrawingRect(r);

// 计算箭头的绘制位置

float top = r.top + topArrowPadding;

float bottom = r.bottom - bottomArrowPadding - bottomPic.getHeight();

float left = r.left + (r.right - r.left - topPic.getWidth()) / 2;

// 计算是否需要绘制

boolean drawTop = false;

boolean drawBottom = false;

if (this.getChildCount() > 0) {

Rect rTop = new Rect();

this.getChildAt(0).getLocalVisibleRect(rTop);

Rect rBottom = new Rect();

View lastChild = this.getChildAt(this.getChildCount() - 1);

lastChild.getLocalVisibleRect(rBottom);

drawTop = (this.getFirstVisiblePosition() > 0 || this

.getFirstVisiblePosition() == 0

&& rTop.top > 0);

drawBottom = (this.getLastVisiblePosition() < this.getAdapter()

.getCount() - 1 || this.getLastVisiblePosition() == this

.getAdapter().getCount() - 1

&& rBottom.bottom < lastChild.getHeight());

}

// 绘出箭头

if (drawTop) {

canvas.drawBitmap(topPic, left, top, paint);

}

if (drawBottom) {

canvas.drawBitmap(bottomPic, left, bottom, paint);

}

}

}

就要点解释一下上面这段代码:

注意构造方法,我们必须继承public ArrowListView(Context context, AttributeSet attrs),这样才可以让这个类在xml定义文件中使用。

还要注意到,这里用了attrs.getAttributeValue来读取XML定义文件中的属性,其实有更好的方法,容我下次再讲解,这里先偷个懒。

convertDisplayUom方法是用来将dp转换成px的,可以看到由于我们用了getAttributeValue的方式,所以需要手动将String转成Float,很麻烦。

最后就是onDraw啦,计算出画箭头的位置,画出来就行了。

接下来就是布局文件的编写了

ArrowListView在XML文件中的使用

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent" android:layout_height="fill_parent"

android:orientation="vertical"

>

<TextView

android:text="Arrow List View Sample"

android:layout_width="fill_parent" android:layout_height="wrap_content"

/>

<net.learningandroid.lib.view.ArrowListView

android:id="@+id/arrowListView"

android:layout_width="fill_parent" android:layout_height="wrap_content"

android:paddingTop="15dp" android:paddingBottom="20dp"

android:layout_margin="10dp"

android:background="@drawable/float_panel"

android:layout_weight="1"

android:cacheColorHint="#FFEDEDED" android:divider="#00EDEDED"

topArrowPadding="5dp" bottomArrowPadding="10dp"

/>

</LinearLayout>

这里需要注意的是自定义控件和其中的属性的写法,不再是ListView了,而是你自己编写的控件类的类名。其它的内容就是定义padding,background,以及取消了分隔线的显示。

用这个布局文件替代上一篇教程中的布局文件,但Adapter的定义不变,因为ArrowListView是继承自ListView的,所以原先的Adapter的使用是一样的。

最后我们来看下效果:

如何?只需要小心的调整ListView的Padding和ArrowPadding的值就可以控制箭头出现的位置,如果需要控制更多,比如更换图片,或者当顶部无内容时让箭头变暗、有内容时变亮,都可以用同样的方法。

并且,如果修改了Attribute的读取方法之后,还可以通过xml文件来指定箭头的图片。

赞助本站

人工智能实验室

相关热词: 顶部 底部 ListView

相关内容
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港