欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

如何提升ListView的运行效果

程序员文章站 2022-04-10 09:44:16
当快速的滚动ListView,而每次都需要去加载一遍,就会成为性能的瓶颈.一.根据参数优化这是可以用ListView中getView()方法中提供的convertView参数,这个参数用于将之前加载好的布局进行缓存,方变后面使用.public class FruitAdapter extends ArrayAdapter { ……@Overridepublic View getView(int position, View convertView, ViewGroup p...

当快速的滚动ListView,而每次都需要去加载一遍,就会成为性能的瓶颈.
一.根据参数优化
这是可以用ListView中getView()方法中提供的convertView参数,这个参数用于将之前加载好的布局进行缓存,方变后面使用.

public class FruitAdapter extends ArrayAdapter<Fruit> { ……
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position);
View view;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
} else {
view = convertView;
}
ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);
fruitImage.setImageResource(fruit.getImageId());
fruitName.setText(fruit.getName());
return view;
}
}

现在子在getView()方法中进行判断,如果convertView为空,则使用LayoutInflater去加载布局,如果不为空则直接对convertView进行重用,这样就提高了ListView的效率.
二.根据内部类形式优化
代码如下:

 @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        Info info = getItem(position);
        View view;
        ViewHolder viewHolder ;
        if(convertView == null) {//如果为空才会去加载.否则不需要去加载,避免重复加载
            view = LayoutInflater.from(getContext()).inflate(resId, null);
            viewHolder = new ViewHolder();
            viewHolder.textView = view.findViewById(R.id.textInfoName);
            viewHolder.imageView = view.findViewById(R.id.imageViewId);
            viewHolder.button = view.findViewById(R.id.buttonInfo);
            view.setTag(viewHolder);//讲viewHolder存在view
        }
        else {
            view = convertView;
            viewHolder = (ViewHolder) view.getTag();//重新获取ViewHolder
        }
        viewHolder.imageView.setImageResource(info.getId());
        viewHolder.textView.setText(info.getName());
        return view;
    }
    class ViewHolder{
        private ImageView imageView;
        private TextView textView;
        private Button button;
    }

三.ListView中的点击事件
在MainActivity中通过增加setOnItemClickList()方法,并实现里面的抽象方法,就会给ListView注册了一个监听器,代码如下:

listViewTemp.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Info info = infoList.get(position);
                Toast.makeText(MainActivity.this, info.getName(),
                        Toast.LENGTH_SHORT).show();
                AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
                dialog.setTitle("this is Dialog");
                dialog.setMessage("你是否要删除信息");
                dialog.setCancelable(false);
                dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                    }
                });
                dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                    }
                });
                dialog.show();
            }
        });

四.单位和尺寸的介绍
指定控件和布局大小的时候最好使用 match_parent 和 wrap_content,尽量避免将控件的宽和高设定一个固定值。不过在有些情况下,仅仅使用 match_parent 和 wrap_content 确实无法满足我们的需求,这时就必须要给控件的宽或高指定一个固定值。在布局文件中指定宽高的固定大小有以下常用单位可供选择:px、pt、dp 和 sp.
px 和 pt 的窘境
px 是像素的意思,即屏幕中可以显示的最小元素单元,
pt 是磅数的意思,1 磅等于 1/72 英寸,一般 pt 都会作为字体的单位来使用.
dp 是密度无关像素的意思,也被称作 dip,和 px 相比,它在不同密度的屏幕中的显示比
例将保持一致
sp 是可伸缩像素的意思,它采用了和 dp 同样的设计理念,解决了文字大小的适配问题

五.编写精美的聊天界面
代码完成此处
六.碎片
碎片(Fragment)是一种可以嵌入在活动中UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用的非常广泛。碎片 和活动非常像,同样都能包含布局,同样都有自己的生命周期.
碎片的使用方式:
1.碎片的简单用发
新建一个左侧的碎片布局left_framgment.xml,
并添加代码如下:

<LinearLayout 
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:orientation="vertical">
	<Button 
		android:id="@+id/buuton"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_gravity+"center_horziontal"
		android:text="Button"
		>
</LinearLayout>

在right_framgment.xml中添加代码如下:

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal">
            android:textSize ="20ap"
            android:text="This is TextView"
        </TextView>
    </LinearLayout>

让后在RightFragment中添加代码入下:

public class RightFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.right_fragment,container,false);
        return view;
        //return super.onCreateView(inflater, container, savedInstanceState);
    }
}

在leftFragment中添加代码如下:

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

       View  view = inflater.inflate(R.layout.left_fragment,container,false);

        //View view = inflater.inflate(R.layout.left_fragment,container,false);

        return view;
    }

二.在碎片中模拟返回栈
通过FramgmentTransaction中提供一个addToBankStack()方法,可以将一个事物添加到返回栈中去,可以在MainActivity中的代码如下:

public class MainActivity extends Activity implements OnClickListener { ……
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
	AnotherRightFragment fragment = new AnotherRightFragment();
	FragmentManager fragmentManager = getFragmentManager();
	FragmentTransaction transaction = fragmentManager.
	beginTransaction();
	transaction.replace(R.id.right_layout, fragment);
	transaction.addToBackStack(null);
	transaction.commit();
	break;
	default:
		break;
}
}
}

这里我们在事物提交之前调用FragmentTransaction的addToBankStack()方法.它可以接受一个名字用于描述返回栈的状态,一般传入null即可.

三.碎片在活动之间的通信
为了方便碎片和活动之间进通信,FragmentManager提供了一个类似于findViewById()的方法,示例代码如下:

RightFragment rightFragment = (RightFragment) getFragmentManager()
.findFragmentById(R.id.right_fragment);

调用 FragmentManager 的 findFragmentById()方法,可以在活动中得到相应碎片的实例,
然后就能轻松地调用碎片里的方法了。掌握了如何在活动中调用碎片里的方法,那在碎片中又该怎样调用活动里的方法呢?其实这就更简单了,在每个碎片中都可以通过调用 getActivity()方法来得到和当前碎片相关联的活动实例,代码如下所示:

MainActivity activity = (MainActivity) getActivity();

有了活动实例之后,在碎片中调用活动里的方法就变得轻而易举了。另外当碎片中需要使用 Context 对象时,也可以使用 getActivity()方法,因为获取到的活动本身就是一个 Context
对象了.

四.碎片的状态和回调

  1. 运行状态
    当一个碎片是可见的,并且它所关联的活动正处于运行状态时,该碎片也处于运行
    状态。
  2. 暂停状态
    当一个活动进入暂停状态时(由于另一个未占满屏幕的活动被添加到了栈顶),与它相关联的可见碎片就会进入到暂停状态。
  3. 停止状态
    当一个活动进入停止状态时,与它相关联的碎片就会进入到停止状态。或者通过调用 FragmentTransaction 的 remove()、replace()方法将碎片从活动中移除,但有在事务提交之前调用 addToBackStack()方法,这时的碎片也会进入到停止状态。总的来说,进入停止状态的碎片对用户来说是完全不可见的,有可能会被系统回收。
  4. 销毁状态
    碎片总是依附于活动而存在的,因此当活动被销毁时,与它相关联的碎片就会进入到销毁状态。或者通过调用 FragmentTransaction 的 remove()、replace()方法将碎片从活动中移除,但在事务提交之前并没有调用 addToBackStack()方法,这时的碎片也会进入
    到销毁状态。

碎片回调的五个方法:

  1. onAttach()
    当碎片和活动建立关联的时候调用。
  2. onCreateView()
    为碎片创建视图(加载布局)时调用。
  3. onActivityCreated()
    确保与碎片相关联的活动一定已经创建完毕的时候调用。
  4. onDestroyView()
    当与碎片关联的视图被移除的时候调用。
  5. onDetach()
    当碎片和活动解除关联的时候调用。

本文地址:https://blog.csdn.net/DZMNLFH/article/details/107410645