ListView快速拖动

我们经常会看见新浪微博,人人的android客户端在显示大量数据的时候,右边会有一个快速拖动按钮,使用它我们可以快速的上下拖动,当我们停止拖动列表时,大约1秒左右,滑块又会消失。这是如何实现的呢?其实很简单,在android的标签中提供了这样一个属性:android:fastScrollEnabled.我们将这个属性设置为true就可以了,但是注意了,listView当中的数据要超过4个屏幕时才会出现这个小滑块,否则小滑块是不会出现的。

如下图所示:

 

接下来我们就来实现这样一个可以迅速滑动的ListView。

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

   <ListView 
       android:id="@+id/myListView"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:fastScrollEnabled="true"
       >
   </ListView>

</RelativeLayout>

在ListView标签中记得要设置fastScrollEnabled的值为true。

List_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
	<TextView
	    android:id="@+id/itemName"
	    android:layout_height="wrap_content"
	    android:layout_width="wrap_content"
	    android:textSize="30sp"
	    />
	<TextView 
	    android:id="@+id/author"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:textSize="10sp"
	    />
</LinearLayout>

主程序MainActivity.java:

package org.list.activity;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.list.adapter.MyListAdapter;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AbsListView;
import android.widget.ListView;
import android.support.v4.app.NavUtils;

public class MainActivity extends Activity {

	private ListView list;
	private List<HashMap<String,String>> data;
	private MyListAdapter adapter;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }

    public void init()
{
    	list=(ListView)findViewById(R.id.myListView);
    	data=new ArrayList<HashMap<String,String>>();
    	adapter=new MyListAdapter(data,this);
    	for(int i=0;i<50;i++)
    	{
    		HashMap map=new HashMap();
    		map.put("itemName", "item"+i);
    		map.put("author", "viking");
    		data.add(map);
    	}
    	list.setAdapter(adapter);
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

接下来是MyListAdapter.java:

package org.list.adapter;

import java.util.HashMap;
import java.util.List;
import java.util.zip.Inflater;

import org.list.activity.R;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyListAdapter extends BaseAdapter
{

	private List<HashMap<String,String>> data;
	private LayoutInflater inflater;
	
	
	public MyListAdapter(List<HashMap<String,String>> data,Context context)
	{
		super();
		this.data = data;
		inflater=LayoutInflater.from(context);
	}

	@Override
	public int getCount()
	{
		if(data!=null)
		{
			return data.size();
		}
		return 0;
	}

	@Override
	public Object getItem(int position)
	{
		if(data!=null)
		{
			return data.get(position);
		}
		return null;
	}

	@Override
	public long getItemId(int position)
	{
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent)
	{
		ViewHolder holder;
		if(convertView==null)
		{
			convertView=inflater.inflate(R.layout.list_item, null);
			holder=new ViewHolder();
			holder.itemName=(TextView) convertView.findViewById(R.id.itemName);
			holder.author=(TextView) convertView.findViewById(R.id.author);
			convertView.setTag(holder);
		}
		else
		{
			holder=(ViewHolder)convertView.getTag();
		}
		HashMap<String,String> map=data.get(position);
		holder.itemName.setText(map.get("itemName").toString());
		holder.author.setText(map.get("author").toString());
		return convertView;
	}
	
	class ViewHolder
	{
		TextView itemName;
		TextView author;
	}

}

到此为止,咱们已经实现了ListView当中的快速滑动的功能了,有人说了,为什么那个快速滑动小块这么难看啊?能不能换成其他图片啊?

  为此我翻了一下帮助文档,发现ListView组件并没有提供修改快速滑动图像的API,因此不能直接修改快速滑块的图像。但可以通过反射技术修改快速滑块图像。

   那我们怎么去使用反射呢?首先我们必须知道对谁进行反射。

我首先查看了ListView的源代码,发现里面变没有fastScrollEnabled这个属性,那么就只能去他的父类AbsListView中去看看。果然,在549行看到了以下代码:

如果mFastScroller这个对象为null,就实例化一个FastScroller。那我们接着进FastScroller类中看看构造方法。


构造方法当中执行了init(context)方法,我们跟过去。


在init方法中有一个useThumbDrawable的方法,它需要一个Drawable的参数。我们可以看见引用的com.android.internal.R.drawable.scrollbar_handle_accelerated_anim2名字是不是跟快速滑动滑块很类似啊?我们继续跟进这个方法。


发现传进去的参数赋值给了一个mThumbDrawable变量。接着在draw方法当中又发现了一下代码:



看来这个变量是要画在画布上的,所以我就猜测这个变量就是我们快速滑动滑块。接下来就好办了,我们用反射技术,把这个值改掉不就行了?

          /首先要通过AbsListView.mFastScroller变量获取到FastScroller对象
           Field field=AbsListView.class.getDeclaredField("mFastScroller");
           //因为mFastScroller是私有的,所以我们必须设置它能够被访问
           field.setAccessible(true);
           Object object=field.get(list);
           //获取FastScroller.mThumbDrawable变量的Field对象
           field=field.getType().getDeclaredField("mThumbDrawable");
           field.setAccessible(true);
           //获取FastScroller.mThumbDrawable变量的值
           Drawable draw=(Drawable)field.get(object);
           //转载新的快速滑动图像
           draw=getResources().getDrawable(R.drawable.ic_launcher);
           //重新设置快速滑动图像
           field.set(object,draw);


 

将以上代码放在onCreate方法中,就可以将快速滑动滑块的图像改掉了。

如下图所示:




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Delphi中,要实现ListView快速实时显示,可以采取以下几个方法: 1. 使用委托机制:通过使用委托机制,可以在一个线程中更新ListView控件,而不会阻塞主线程。可以创建一个委托过程,该过程负责将数据添加到ListView中,然后在需要更新ListView时调用该委托过程。这样可以确保数据实时显示在ListView中,而不会影响应用程序的响应性能。 2. 使用多线程:可以创建一个独立的线程来处理数据更新和ListView的刷新,这样可以避免在主线程中过多的计算和处理,从而提高ListView的响应速度。可以使用TThread类来创建一个后台线程,该线程负责更新数据,并通过发送消息或使用同步方法来通知主线程进行ListView的更新。 3. 使用虚拟模式:ListView的虚拟模式可以提高列表控件的性能和响应速度。在虚拟模式下,ListView只会在需要显示时加载可见项目的数据,而不会加载整个数据集。可以通过设置ListView的OwnerData属性为True,并实现OnData事件来实现虚拟模式。 4. 数据分页:如果数据量非常大,可以考虑将数据进行分页显示。每次只加载一页的数据到ListView中,当需要显示更多数据时,再加载下一页的数据。这样可以避免一次性加载大量数据造成的性能问题,提高ListView的实时显示速度。 综上所述,通过使用委托机制、多线程、虚拟模式和数据分页等方法,可以实现Delphi ListView快速实时显示,提高应用程序的响应速度和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值