当前位置: 移动技术网 > 移动技术>移动开发>Android > 如何提升ListView的运行效果

如何提升ListView的运行效果

2020年07月23日  | 移动技术网移动技术  | 我要评论

当快速的滚动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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网