1.ListView
1.使用步骤
- 布局里引入控件
<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"
tools:context=".MainActivity" >
<ListView
android:id="@+id/lv"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
- 查找控件,设置控制器
public class MainActivity extends Activity {
// mvc中的view,视图
private ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 查找视图
lv = (ListView) findViewById(R.id.lv);
// 设置控制器 controller
lv.setAdapter(new MyAdapter());
}
//控制器 用来控制listview如何显示
private class MyAdapter extends BaseAdapter {
// 控制listview里面有多少个item
@Override
public int getCount() {
return 30;
}
// 返回某个位置显示的view对象。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = new TextView(MainActivity.this);
tv.setText("我是文本:" + position);
tv.setTextSize(24);
return tv;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
}
}
ListView复用的原理:
1.当我们滑动listview的时候,每当一个item看不见的时候,那么那个item就可以被复用起来了,也就是成为了convertView,那个时候convertView就不为null了。
2.所谓的复用,其实本质是就是item的view对象没有真正的被垃圾回收器回收掉,而是重新将身上的数据给换掉了,看起来好像是出现了一个新的item而已。
3.对ListView 进行优化的最简单有效的措施就是复用getView 方法中的convertView 对象。
4.convertView来自缓存池,缓存池由ListView 维护,缓存池中的数据来自getView 方法的返回值,也就是说getView方法的返回值用完后并没有“浪费”,而是被系统放到ListView 的缓存池里了。
5.缓存池的大小=屏幕显示的条目数+1,当滑动屏幕时,被隐藏的项会作为缓存对象,作为getView 的参数传递进来。
6.只需修改此缓存对象的数据,就可以直接使用,而不需要再重新new 一个新的对象,节省了内存,防止内存溢出。
- 优化后的代码
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = null;
if (null == convertView) {
//如果缓存中没有数据则需要创建一个新的TextView
tv = new TextView(MainActivity.this);
}else{
//如果缓存中有数据则直接强转即可
tv = (TextView) convertView;
}
tv.setText("我是文本:" + position);
tv.setTextSize(24);
return tv;
}
inflate将一个布局文件转化为Veiw对象
@Override
public View getView(final int position, View convertView, ViewGroup parent){
View view = null;
if (convertView == null) {
// 把一个布局xml文件转化成view对象
view = View.inflate(MainActivity.this, R.layout.item, null);
} else {
view = convertView;
}
// 在view里面查找子控件
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
ImageView iv_sex = (ImageView) view.findViewById(R.id.iv_sex);
}
- BaseAdapter适配器中有一个方法adapter.notifyDataSetChanged()该方法是通知适配器进行数据刷新,会自己调用adapter中的getCount()和getView()方法进行数据的刷新。
/**
* 获取数据库的全部记录,刷新显示数据
*/
private void refreshData() {
students = dao.findAll();
if (adapter == null) {
//第一次显示数据
adapter = new MyAdapter();
lv.setAdapter(adapter);
}else{
//通知数据适配器更新数据,而不是new出来新的数据适配器
adapter.notifyDataSetChanged();
}
}
- ArrayAdapter
String[] objects = new String[]{"Animation","App","content","Media","NFC","OS"};
/**
* 第一个参数是:上下文
* 第二个参数是:布局文件的id,这里使用Android 系统提供的简单布局
* 第三个参数是:要显示的数据,数组或者List 集合都行
*/
lv.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, objects));
- SimpleAdapter
2.对话框
对话框的初始化
AlertDialog.Builder builder = new Builder(当前Activity的上下文);
对话框设置属性
builder.setTitle(title);-->设置标题
builder.setMessage(msg);-->设置提醒信息
设置对话框按钮
builder.setPositiveButton(按钮文字,new DialogInterface.OnClickListener());-->最右边的按钮
builder.setNegativeButton(按钮文字,new DialogInterface.OnClickListener());-->最左边的按钮
builder.setNeutralButton(按钮文字,new DialogInterface.OnClickListener());-->中间的按钮
对话框显示
builder.show();
对话框样式
setSingleChoiceItems()-->单选
setMultiChoiceItems()-->多选
ProgressDialog -->进度条
- 对话框
//builder可以理解成一个构造器,构造对话框所需要的一些数据,最后由dialog来进行显示
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("警告:");
builder.setMessage("若练此功,必先自宫,是否继续?");
builder.setPositiveButton("确定自宫", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "啊....", 0).show();
}
});
builder.setNegativeButton("想想再说", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "如不自宫,一定不成功", 0).show();
}
});
AlertDialog dialog = builder.create();
dialog.setCancelable(false);//设置其他空白区域点击是否可以关闭我们的dialog
dialog.show();//注意一定要调用show否则显示不了对话框
- 正在加载对话框
final ProgressDialog pd = new ProgressDialog(this);
pd.setTitle("提醒");
pd.setMessage("正在加载数据...请稍后");
pd.show();
new Thread() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
pd.dismiss();//关闭对话框
};
}.start();
- 进度条对话框
final ProgressDialog pd = new ProgressDialog(this);
//进度条的风格为水平进度条
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMax(100);//进度条的最大值
pd.setTitle("提醒");
pd.setMessage("正在加载数据...请稍后");
pd.show();
new Thread() {
public void run() {
for (int i = 0; i <= 100; i++) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
pd.setProgress(i);//设置当前进度值
}
pd.dismiss();
};
}.start();
3.Android国际化
文字国际化:在res文件下创建values–xx文件夹,在里面创建strings.xml文件,在里面写对应的语言
图片国际化:drawable-xxx里面的资源名字要起一样的,这样系统就能根据当前的语言自动去寻找对应的文件夹资源
4.样式和主题
- 配置样式:
//在style文件里设置,如果想继承系统自带的主题或者样式,指定 parent=“需要继承的样式”;如果需要修改继承样式里的某一样,在自定义样式里面重写需要修改的属性即可。
<style name="text_content_style">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#0000ff</item>
<item name="android:textSize">20sp</item>
</style>
<style name="text_title_style" parent="@style/text_content_style">
<item name="android:textSize">25sp</item>
</style>
<!-- 该方式也可以指定父类为text_content_style,但是不建议 -->
<style name="text_content_style.sub">
<item name="android:textSize">28sp</item>
</style>
//这样做的目的是为了达到复用,代码的简洁,统一修改的便捷。 当一个布局界面有大量相同重复的布局属性参数时,就可以使用抽取style的方式来实现
<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
style="@style/text_title_style"
android:text="@string/hello_world" />
<TextView
style="@style/text_content_style"
android:text="@string/hello_world" />
<TextView
style="@style/text_content_style.sub"
android:text="@string/hello_world" />
<TextView
style="@style/text_content_style"
android:text="@string/hello_world" />
<TextView
style="@style/text_content_style"
android:text="@string/hello_world" />
<TextView
style="@style/text_content_style"
android:text="@string/hello_world" />
</LinearLayout>
- 设置主题
- 可以通过设置theme属性参数来修改整个应用程序或者单个界面的主题风格
在清单文件里面配置 theme="@style:..."
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
>
指定style为AppTheme则整个应用程序的主题风格即为AppTheme的风格,当然也可以修改AppTheme的风格,将当前主题添加一个没有标题栏的风格:
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:windowNoTitle">true</item>
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
或者自己定义一个theme:
<style name="my_app_theme">
<item name="android:windowNoTitle">true</item>
<item name="android:background">#440000ff</item>
</style>
也可以在代码中设置主题:
在代码设置 setTheme(ResId) 此方法必须在setContentView之前调用
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.my_app_theme);
setContentView(R.layout.activity_main);
}
}