android qq切换界面,Android应用中使用ViewPager实现类似QQ的界面切换效果

这几天在研究viewpager,简单的写一下如何使用viewpager实现类似于qq的“最近联系人、好友、群组”的界面切换(不知道他们是不是用这个方法实现的)。

viewpager已经在android-sdk中加入了,具体的位置在%android_sdk_home%\android-compatibility\v4,%android_sdk_home%是你的android-sdk-windows目录。

好,下面放一张效果图:

63a23ff9422791d1c2e36eb3c9baa5ee.png

步骤一:新建一个工程,我的是viewpager

步骤二:导入jar包

具体如下:

右键工程--properties--单击左侧java build path--单击右侧libraries标签--单击右侧add external jars--选择上面描述位置的jar包,保存

步骤三:编写一个主界面,加入android.support.v4.view.viewpager组件

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/hello" />

android:id="@+id/mviewpager"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

/>

步骤四:编写三个要添加进来的界面

界面都很简单,随便写的

界面1

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#ff0000"

android:orientation="vertical" >

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="layout1" />

界面2

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#00ff00"

android:orientation="vertical" >

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="layout2" />

界面3

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#0000ff"

android:orientation="vertical" >

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="layout3" />

步骤五:编写主类,我的名字是叫viewpageractivity

package com.carter.viewpager;

import java.util.arraylist;

import java.util.list;

import java.util.zip.inflater;

import android.app.activity;

import android.app.activitygroup;

import android.content.intent;

import android.os.bundle;

import android.support.v4.view.pageradapter;

import android.support.v4.view.viewpager;

import android.support.v4.view.viewpager.onpagechangelistener;

import android.util.log;

import android.view.layoutinflater;

import android.view.view;

import android.view.viewgroup;

public class viewpageractivity extends activitygroup {

/**

* 能够支持滑动的组件

*/

viewpager mviewpager;

/**

* viewpager 需要设置该adapter才能实现添加界面,

* 该adapter继承自pageradapter

*/

mypageradapter adapter;

/**

* 用于保存三个界面

*/

list list;

/**

* 用于生成界面

*/

layoutinflater minflater;

/** called when the activity is first created. */

@override

public void oncreate(bundle savedinstancestate) {

super.oncreate(savedinstancestate);

setcontentview(r.layout.main);

minflater = this.getlayoutinflater();

/**

* 添加进来三个界面到list,用于初始化pageradapter

*/

list = new arraylist();

list.add(this.getlocalactivitymanager().startactivity("layout1", new intent(viewpageractivity.this, layout1activity.class)).getdecorview());

list.add(minflater.inflate(r.layout.layout2, null));

list.add(minflater.inflate(r.layout.layout3, null));

mviewpager = (viewpager)findviewbyid(r.id.mviewpager);

adapter = new mypageradapter(list);

mviewpager.setadapter(adapter);

/**

* 为viewpager添加pagechangelistener,在回调的方法中可以完成其他的事情,例如处理一些界面标签的转换之类的,如果你有标签栏的话

*/

mviewpager.setonpagechangelistener(new onpagechangelistener() {

@override

public void onpageselected(int arg0) {

// todo auto-generated method stub

log.i("carter", "onpageselected");

}

@override

public void onpagescrolled(int arg0, float arg1, int arg2) {

// todo auto-generated method stub

}

@override

public void onpagescrollstatechanged(int arg0) {

// todo auto-generated method stub

}

});

}

class mypageradapter extends pageradapter

{

list mlist;

public mypageradapter(list list){

mlist = list;

}

@override

public int getcount() {

// todo auto-generated method stub

return mlist.size();

}

@override

public boolean isviewfromobject(view arg0, object arg1) {

// todo auto-generated method stub

return arg0 == (arg1);

}

@override

public void destroyitem(view container, int position, object object) {

// todo auto-generated method stub

((viewpager)container).removeview(mlist.get(position));

}

@override

public object instantiateitem(view container, int position) {

// todo auto-generated method stub

((viewpager)container).addview(mlist.get(position), 0);

return mlist.get(position);

}

@override

public void finishupdate(viewgroup container) {

// todo auto-generated method stub

super.finishupdate(container);

}

}

}

代码解读:

1、在上面重写了pageradapter,在里面最重要的方法就是

@override

public object instantiateitem(view container, int position) {

// todo auto-generated method stub

((viewpager)container).addview(mlist.get(position), 0);

return mlist.get(position);

}

具体为什么每次都是addview到0的位置,目前我还不知道,这个也是从网上找了一个方法看到的。

2、在初始化list的时候,里面包含的内容是一个个的view元素,在我的了解范围内有两种方法

第一种就是通过添加window的getdecorview()来得到一个view;

第二种就是通过layoutinflater,从xml中生成一个view。

需要注意的是,第一种方法,需要主类继承自activitygroup,这样才能在添加时使用getlocalactivitymanager以及之后的方法,需要生成的activity,例如本例中的layout1activity,要在androidmanifest.xml中声明。

/**

* 添加进来三个界面到list,用于初始化pageradapter

*/

list = new arraylist();

list.add(this.getlocalactivitymanager().startactivity("layout1", new intent(viewpageractivity.this, layout1activity.class)).getdecorview());

list.add(minflater.inflate(r.layout.layout2, null));

list.add(minflater.inflate(r.layout.layout3, null));

3、如果只是从xml生成view来添加的话,完全可以移除继承activitygroup。

4、如果使用startactivity的方法来启动,需要添加进来的几个activity,是一起在加入时就初始化的,可以通过在oncreate()方法中打log看出来。

ps:如何解决android下viewpager和pageradapter中调用notifydatasetchanged失效的问题具体讲解如下:

google在android 3.0sdk中推出的viewpager控件很大程度上满足了开发者开发页面左右移动切换的功能,使用非常方便。但是使用中发现,在删除或者修改数据的时候,pageradapter无法像baseadapter那样仅通过notifydatasetchanged方法通知刷新view。

最基本的方法:

针对于child view比较简单的情况(例如仅有textview、imageview等,没有listview等展示数据的情况),可以在自己的adapter中加入代码:

@override

public int getitemposition(object object) {

return position_none;

}

这样既可达到一般情况下要求的效果。

存在的问题:

这不是pageradapter中的bug,通常情况下,调用notifydatasetchanged方法会让viewpager通过adapter的getitemposition方法查询一遍所有child view,这种情况下,所有child view位置均为position_none,表示所有的child view都不存在,viewpager会调用destroyitem方法销毁,并且重新生成,加大系统开销,并在一些复杂情况下导致逻辑问题。特别是对于只是希望更新child view内容的时候,造成了完全不必要的开销。

更有效地方法:

更为靠谱的方法是因地制宜,根据自己的需求来实现notifydatasetchanged的功能,比如,在仅需要对某个view内容进行更新时,在instantiateitem()时,用view.settag方法加入标志,在需要更新信息时,通过findviewwithtag的方法找到对应的view进行更新即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值