Android组件

Android组件

Android Adapter

Android Adapter一般用于ListView,GridView等控件,用于控制这些控件的内容样式等。

Android Adapter 的类的结构:
在这里插入图片描述

  • BaseAdapter:抽象类,实际开发中我们会继承这个类并且重写相关方法,用得最多的一个Adapter!
  • ArrayAdapter:支持泛型操作,最简单的一个Adapter,只能展现一行文字~
  • SimpleAdapter:同样具有良好扩展性的一个Adapter,可以自定义多种效果!
  • SimpleCursorAdapter:用于显示简单文本类型的listView,一般在数据库那里会用到,不过有点过时, 不推荐使用!

以ListView为例:

//创建一个simpleAdapter
SimpleAdapter myAdapter = new SimpleAdapter(getApplicationContext(), listitem, R.layout.list_item, new String[]{"touxiang", "name", "says"}, new int[]{R.id.imgtou, R.id.name, R.id.says});
ListView listView = (ListView) findViewById(R.id.list_test);
listView.setAdapter(myAdapter);

一般情况下,都会重写BaseAdapter,并重写其getView()方法。

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    if(convertView == null){
        convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
        holder = new ViewHolder();
        holder.img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
        holder.txt_aName = (TextView) convertView.findViewById(R.id.txt_aName);
        holder.txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak);
        convertView.setTag(holder);   //将Holder存储到convertView中
    }else{
        holder = (ViewHolder) convertView.getTag();
    }
    holder.img_icon.setBackgroundResource(mData.get(position).getaIcon());
    holder.txt_aName.setText(mData.get(position).getaName());
    holder.txt_aSpeak.setText(mData.get(position).getaSpeak());
    return convertView;
}

static class ViewHolder{
    ImageView img_icon;
    TextView txt_aName;
    TextView txt_aSpeak;
}
ListView

Adapter是数据和ListView之间的适配器

使用ListView需要创建:

  • 一个数据类,其中包含一个item中的控件。
  • 适配器类,继承BaseAdapter,重写getView方法。其中getView方法中,通过find方法得到各控件,在以数据类中的数据设置ListView的样式
  • 在mainActivity方法中创建一个 List<数据类> ,并用这个list接收所有创建的数据。然后用list初始化Adapter对象,再用listView的setAdapter方法设置Adapter,则成功创建ListView。
//Adapter类的getView方法实例
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    if(convertView == null){
        convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
        holder = new ViewHolder();
        holder.img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
        holder.txt_aName = (TextView) convertView.findViewById(R.id.txt_aName);
        holder.txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak);
        convertView.setTag(holder);   //将Holder存储到convertView中
    }else{
        holder = (ViewHolder) convertView.getTag();
    }
    holder.img_icon.setBackgroundResource(mData.get(position).getaIcon());
    holder.txt_aName.setText(mData.get(position).getaName());
    holder.txt_aSpeak.setText(mData.get(position).getaSpeak());
    return convertView;
}

static class ViewHolder{
    ImageView img_icon;
    TextView txt_aName;
    TextView txt_aSpeak;
}

Toast

Toast是一种很方便的消息提示框,会在 屏幕中显示一个消息提示框,没任何按钮,也不会获得焦点一段时间过后自动消失。

Toast toast = Toast.makeText(global_context, str, showTime);            
toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL , 0, 0);  //设置显示位置
toast.setDuration(Toast.LENGTH_LONG);
TextView v = (TextView) toast.getView().findViewById(android.R.id.message);
v.setTextColor(Color.YELLOW);     //设置字体颜色
toast.show();   

系统自带Toast采用的是队列的方式, 等当前Toast消失后, 下一个Toast才能显示出来

Handler消息传递机制

由于在Android中多个线程操作UI组件,可能会导致线程安全问题,所以只允许在UI线程中修改Activity中的UI组件,所以使用Handle来修改UI组件的属性值。当app第一次启动时,Android会同时启动一条UI线程,负责处理与UI相关的事件,比如出发事件,和修改UI组件等。

Handle的执行流程图:
在这里插入图片描述
当我们的子线程想修改Activity中的UI组件时,我们可以新建一个Handler对象,通过这个对象向主线程发送信息;而我们发送的信息会先到主线程的MessageQueue进行等待,由Looper按先入先出顺序取出,再根据message对象的what属性分发给对应的Handler进行处理!

Handle相应方法:

  • void handleMessage(Message msg):处理消息的方法,通常是用于被重写!
  • sendEmptyMessage(int what):发送空消息
  • sendEmptyMessageDelayed(int what,long delayMillis):指定延时多少毫秒后发送空信息
  • sendMessage(Message msg):立即发送信息
  • sendMessageDelayed(Message msg):指定延时多少毫秒后发送信息
  • final boolean hasMessage(int what):检查消息队列中是否包含what属性为指定值的消息 如果是参数为(int what,Object object):除了判断what属性,还需要判断Object属性是否为指定对象的消息

Android 四大组件

android四大组件都需要在AndroidMainfest.xml中进行配置。
Activity

Activity是一个应用程序的组件,他在屏幕上提供了一个区域,允许用户在上面做一些交互性的操作, 比如打电话,照相,发送邮件,或者显示一个地图!Activity可以理解成一个绘制用户界面的窗口, 而这个窗口可以填满整个屏幕,也可能比屏幕小或者浮动在其他窗口的上方!
Activity
在这里插入图片描述

启动Activity的方式
  1. 显示启动
    ① 最常见
startActivity(new Intent("当前Act.this","要启动的Act.class"))

②通过Intent的ComponentName:

ComponentName cn = new ComponentName("当前Act的全限定类名","启动Act的全限定类名") ;
Intent intent = new Intent() ;
intent.setComponent(cn) ;
startActivity(intent) ;

③初始化Intent时指定包名:

Intent intent = new Intent("android.intent.action.MAIN");
intent.setClassName("当前Act的全限定类名","启动Act的全限定类名");
startActivity(intent);
  1. 隐式启动:通过Intent-filter的Action,Category或data来实现 这个是通过Intent的 intent-filter**来实现的
<activity>
	<intent-filter>
		<action android:name="my_action"/>
		<categroy android:name="my_category"/>
		<categroy android:name="android.intent.category.DEFAULT"/>
	</intent-filter>
</activity>

Java:
Intent it = new Intent();
it.setAction("my_action");
it.addCategory("my_category");
startActivity(it);
  1. 另外还有一个直接通过包名启动apk的:
Intent intent = getPackageManager().getLaunchIntentForPackage
("apk第一个启动的Activity的全限定类名") ;
if(intent != null) startActivity(intent) ;
Activity 间的数据传递

在这里插入图片描述

多个Activity交互

在这里插入图片描述

Service
启动Service的方式:
1)StartService()启动Service
2)BindService()启动Service
  • onCreate():当Service第一次被创建后立即回调该方法,该方法在整个生命周期 中只会调用一次!
  • onDestory():当Service被关闭时会回调该方法,该方法只会回调一次!
  • onStartCommand(intent,flag,startId):早期版本是onStart(intent,startId), 当客户端调用startService(Intent)方法时会回调,可多次调用StartService方法, 但不会再创建新的Service对象,而是继续复用前面产生的Service对象,但会继续回调 onStartCommand()方法!
  • IBinder onOnbind(intent):该方法是Service都必须实现的方法,该方法会返回一个 IBinder对象,app通过该对象与Service组件进行通信!
  • onUnbind(intent):当该Service上绑定的所有客户端都断开时会回调该方法!
  1. StartService启动Service
①首次启动会创建一个Service实例,依次调用onCreate()和onStartCommand()方法,此时Service 进入运行状态,如果再次调用StartService启动Service,将不会再创建新的Service对象, 系统会直接复用前面创建的Service对象,调用它的onStartCommand()方法!
②但这样的Service与它的调用者无必然的联系,就是说当调用者结束了自己的生命周期, 但是只要不调用stopService,那么Service还是会继续运行的!
③无论启动了多少次Service,只需调用一次StopService即可停掉Service
  1. BindService启动Service
①当首次使用bindService绑定一个Service时,系统会实例化一个Service实例,并调用其onCreate()和onBind()方法,然后调用者就可以通过IBinder和Service进行交互了,此后如果再次使用bindService绑定Service,系统不会创建新的Sevice实例,也不会再调用onBind()方法,只会直接把IBinder对象传递给其他后来增加的客户端!
②如果我们解除与服务的绑定,只需调用unbindService(),此时onUnbind和onDestory方法将会被调用!这是一个客户端的情况,假如是多个客户端绑定同一个Service的话,情况如下 当一个客户完成和service之间的互动后,它调用 unbindService() 方法来解除绑定。当所有的客户端都和service解除绑定后,系统会销毁service。(除非service也被startService()方法开启)
③另外,和上面那张情况不同,bindService模式下的Service是与调用者相互关联的,可以理解为 "一条绳子上的蚂蚱",要死一起死,在bindService后,一旦调用者销毁,那么Service也立即终止!
通过BindService调用Service时调用的Context的bindService的解析 bindService(Intent Service,ServiceConnection conn,int flags)
service:通过该intent指定要启动的Service
conn:ServiceConnection对象,用户监听访问者与Service间的连接情况, 连接成功回调该对象中的onServiceConnected(ComponentName,IBinder)方法; 如果Service所在的宿主由于异常终止或者其他原因终止,导致Service与访问者间断开 连接时调用onServiceDisconnected(CompanentName)方法,主动通过unBindService() 方法断开并不会调用上述方法!
flags:指定绑定时是否自动创建Service(如果Service还未创建), 参数可以是0(不自动创建),BIND_AUTO_CREATE(自动创建)
  1. StartService启动Service后bindService绑定
如果Service已经由某个客户端通过StartService()启动,接下来由其他客户端 再调用bindService()绑定到该Service后调用unbindService()解除绑定最后在 调用bindService()绑定到Service的话,此时所触发的生命周期方法如下:
onCreate( )->onStartCommand( )->onBind( )->onUnbind( )->onRebind( )
PS:前提是:onUnbind()方法返回true!!! 这里或许部分读者有疑惑了,调用了unbindService后Service不是应该调用 onDistory()方法么!其实这是因为这个Service是由我们的StartService来启动的 ,所以你调用onUnbind()方法取消绑定,Service也是不会终止的!
得出的结论: 假如我们使用bindService来绑定一个启动的Service,注意是已经启动的Service!!! 系统只是将Service的内部IBinder对象传递给Activity,并不会将Service的生命周期 与Activity绑定,因此调用unBindService( )方法取消绑定时,Service也不会被销毁!
BroadcastReceiver

广播,用于多个app之间的交互。在AndroidManifest.xml里通过<receive>标签声明。

<receiver 
    //此广播接收者类是mBroadcastReceiver
    android:name=".mBroadcastReceiver" >
    //用于接收网络状态改变时发出的广播
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

参考的博客和文档:
https://www.runoob.com/w3cnote/android-tutorial-baseadapter.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值