当快速的滚动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
对象了.
四.碎片的状态和回调
- 运行状态
当一个碎片是可见的,并且它所关联的活动正处于运行状态时,该碎片也处于运行
状态。 - 暂停状态
当一个活动进入暂停状态时(由于另一个未占满屏幕的活动被添加到了栈顶),与它相关联的可见碎片就会进入到暂停状态。 - 停止状态
当一个活动进入停止状态时,与它相关联的碎片就会进入到停止状态。或者通过调用 FragmentTransaction 的 remove()、replace()方法将碎片从活动中移除,但有在事务提交之前调用 addToBackStack()方法,这时的碎片也会进入到停止状态。总的来说,进入停止状态的碎片对用户来说是完全不可见的,有可能会被系统回收。 - 销毁状态
碎片总是依附于活动而存在的,因此当活动被销毁时,与它相关联的碎片就会进入到销毁状态。或者通过调用 FragmentTransaction 的 remove()、replace()方法将碎片从活动中移除,但在事务提交之前并没有调用 addToBackStack()方法,这时的碎片也会进入
到销毁状态。
碎片回调的五个方法:
- onAttach()
当碎片和活动建立关联的时候调用。 - onCreateView()
为碎片创建视图(加载布局)时调用。 - onActivityCreated()
确保与碎片相关联的活动一定已经创建完毕的时候调用。 - onDestroyView()
当与碎片关联的视图被移除的时候调用。 - onDetach()
当碎片和活动解除关联的时候调用。