热门资讯 点击: 2013-01-11
Android插件化的思考——仿QQ一键换肤,思考比实现更重要!
Android插件化的思考——仿QQ一键
换肤,思考比实现更重要!
关于QQ的换肤,他们的实现思路我不是很清楚,但是你可以看一下这张换肤的截图
我们想使用哪个主题就直接下载就好了,这一实现的过程我们大致的可以猜想:
首选是下载到本地指定文件夹,然后通过插件加载到我们的apk,最后应用为皮肤,逻辑大致是这样的逻辑了,那我们是不是应该动动手啊动动脑?
首选我们新建一个工程好了——
PlugInSample
一.实现思路
其实说起来,这个插件的实现思路,确实是比较的麻烦,思来想去,还是一种办法比较靠谱,首先,我们刻意去获取手机上所有的安装的/未安装的程序,过滤掉没用的,留下我们的插件apk,我们的插件apk怎么去辨别呢?我们可用通过设置sharedUserId,然后用实体类把插件名称和包名保存下来,有了包名,就比较好说了,我们可用获取插件的上下文,也就是createPackageContext,然后就可以做点坏事了,我们可以去剖析我们的R文件
因为R文件里面都是静态的原因,我们很容易联想到反射机制,是的,我们可以再一次过
滤掉无用的信息,通过我们的PathClassLoader去加载,访问我们的内加载器反射到我们的图片ID,也就是后面的那段数字,然后,嘿嘿,就可以使用了,是不是思路比较清晰了?这里要注意的就是图片命名统一,这样就比较号过来,那具体我们应该怎么做?
二.PlugIn主程序
我们写一个Spinner,每次切换就直接换肤怎么样?OK,每次换的时候就从插件APK里加载我们的图片资源,看起来是比较顺畅的逻辑,那我们具体该怎么做呢?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/mLinearLayout"
xmlns:android="
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Spinner
android:id="@+id/mSpinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
1.初始化
/**
* 初始化View
*/
private void initView() {
//初始化控件
mSpinner = (Spinner) findViewById(R.id.mSpinner);
}
当然,我这刚应用就一个View,但是实际开发当中可不止,所以步骤一定要明了
2.获取所有的插件
/**
* 获取手机里的插件
*
* @return
*/
private List<PlugInBean> findPlugIn() {
mList = new ArrayList<>();
//获取相关信息
PackageManager mPackageManager = getPackageManager();
//获取卸载/未安装的安装包信息
List<PackageInfo> mUninstallPackage = mPackageManager.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES); //遍历拿到我们的信息
for (PackageInfo info : mUninstallPackage) {
String pkgNmae = info.packageName;
//获取shareId,根据id判断是否是我们的ID
String shareUserId = info.sharedUserId;
if (!TextUtils.isEmpty(shareUserId)) {
//如果id相同
if (shareUserId.equals("com.liuguilin.share")) {
//且排除自己的包名
if (!pkgNmae.equals(getPackageName())) {
//这个就是我们的插件了
String lable = mPackageManager.getApplicationLabel(info.applicationInfo).toString();
PlugInBean bean = new PlugInBean();
bean.setLabelNmae(lable);
bean.setPackagNmae(pkgNmae);
mList.add(bean);
}
}
}
}
return mList;{android仿qq发表说说}.
}
这里就是过滤了一下,通过sharedUserId去拿到我们的插件APK了,然后就可以拿到我们的包名和应用名,他返回给我们一个数据集
//所有的插件
List<PlugInBean> allPlugIn = findPlugIn();
3.加载皮肤数据
/**
* 加载皮肤
*
* @param allPlugIn
*/
private void LoadSkin(List<PlugInBean> allPlugIn) {
//遍历
for (PlugInBean bean : allPlugIn) {
HashMap<String, Object> mMap = new HashMap<>();
mMap.put("lable", bean.getLabelNmae());
mMap.put("package", bean.getPackagNmae());
mData.add(mMap);
}
//建立Adapter并且绑定数据源
mAdapter = new SimpleAdapter(this, mData, android.R.layout.simple_list_item_1, new String[]{"lable"}, new int[]{android.R.id.text1});
//设置数据
mSpinner.setAdapter(mAdapter);
//设置监听事件
mSpinner.setOnItemSelectedListener(this);
}
我们通过刚才的数据集便可以把我们拿到的数据给直接显示出来了,这里其实可以判断一下size是否为0,如果为0的话也就没有插件,OK,我们设置adapter和监听,做到这里,其实你可以运行一下,虽然我们现在什么都没有,我们要做的还有很多
4.获取插件Context
/**
* 选中监听事件
*
* @param adapterView
* @param view
* @param i
* @param l
*/
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { PlugInBean bean = mList.get(i);
//插件的包名
String packageNmae = bean.getPackagNmae();
Context mContext = null;
try {
//无视警告 访问代码
mContext = createPackageContext(packageNmae, CONTEXT_IGNORE_SECURITY | CONTEXT_INCLUDE_CODE);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
//获取图片
getImg(packageNmae, mContext);
//通过ID加载插件的图片
getWindow().setBackgroundDrawable(mContext.getResources().getDrawable(mListId.get(i))); }
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
这里的代码就比较有意思,一定要仔细看,我们首先拿到选中的item的包名,通过我们的createPackageContext拿到我们的上下文,通过这两个我们可用拿到我们的资源ID,也就是R清单里面的ID,然后直接设置window的背景,这里为了好看才设置window的背景,实际上你要设置的是你根布局的背景,那好,我们来看一下如何通过插件的上下文和包名拿到R清单的资源ID
5.获取插件图片 / 返回图片R文件ID / 反射R文件
/**
* 获取插件图片 / 返回图片R文件ID / 反射R文件
*
* @param packageNmae
* @param mContext
*/
private void getImg(String packageNmae, Context mContext) {
//类加载器反射插件
PathClassLoader pathClass = new PathClassLoader(mContext.getPackageResourcePath(), ClassLoader.getSystemClassLoader()); //反射 $ 访问类加载器
try {
Class<?> forNmae = Class.forName(packageNmae + ".R$drawable", true, pathClass);
//拿到所有图片的id
Field[] files = forNmae.getDeclaredFields();
for (Field id : files) {
//过滤 / 这里的命名可以注意一下
if (id.getName().startsWith("img")) {
int drawId = 0;
////这就是我们图片R下的ID
drawId = id.getInt(R.drawable.class);
mListId.add(drawId);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
仿QQ聊天系统课程设计
目录
绪论................................................................................................................................ 2 一.需求分析................................................................................................................ 2
1.1软件功能需求分析.......................................................................................... 3 1.2 安全需求分析................................................................................................. 3 二.总体设计................................................................................................................ 4
2.1 软件结构图..................................................................................................... 4 2.2 功能描述......................................................................................................... 4
2.2.1注册功能概要..................................................................................... 5 2.2.2登录功能概要..................................................................................... 5 2.2.3聊天功能概要..................................................................................... 6 2.3 安全设计......................................................................................................... 7 三.数据库设计............................................................................................................ 7
3.1概念结构设计.................................................................................................. 7 3.2逻辑结构设计.................................................................................................. 8 3.3物理结构设计.................................................................................................. 8 四.详细设计................................................................................................................ 8
4.1 用户聊天模块总体流程图............................................................................ 9 4.2 服务端模块.................................................................................................... 9 4.3 客户端模块.................................................................................................. 10 五.编码...................................................................................................................... 15 六.结论...................................................................................................................... 17 学习体会...................................................................................................................... 18 致谢.............................................................................................................................. 18 参考文献...................................................................................................................... 18
绪论
随着现代技术的不断输入和信息化的广泛普及,移动网络作为一种新兴事物,在近些年得到了前所未有的普及和深入,移动网络上的各种应用层出不穷,给各个阶层、各个年龄段的用户提供了不同的个性化的服务。而现代中小型企业的领导认识到进一步提高企业信息化的必要性。为使企业能在瞬息万变的信息时代生存下去,适应激烈的市场竞争,现代企业要求加强员工之间的交流和通信能力,尤其是领导和员工之间的共同能力,实时的交流系统就是在这种条件下诞生的。
在这个信息化时代,手机已成为继固话之后最为通俗的交流工具,“聊天”成了生活的必需品,这就有了系统下人与人之间的多样会话方式—QQ聊天。传统会话聊天或许是面对面闲话家常或许是通过打电话进行交流,但都存在各种不便及弊端 。而手机QQ,在手机系统下,占用手机相对很小的空间,系统的记录了QQ好友的信息,不仅突破了各种条件的束缚,减轻了机主的负担,更方便了使用者的通讯交流。
综上所述,本课题主要研究基于Android的移动聊天系统,以更好的用户体验性为目的开发出界面简洁,用户易操作的移动即时通信聊天工具。该聊天工具的主要功能:用户注册,登录,好友一对一聊天,添加新好友,修改个人信息等。在该即时通信工具中利用Bmob实现Android端与Bmob服务端的数据操作。Bmob对数据的增删改查找做了很好地封装,以及其批量的处理。客户端之间通过服务器对数据的转发实现相互通信。
一.需求分析
随着经济全球化的推进以及企业激烈的竞争,改善企业内部及整个供应链各环节的管理、调度资源配置,迅速适应客户的新需求和市场新机遇,是企业赢得竞争胜利的决定性因素。
需求分析是软件分析中的一个重要步骤。它的基本任务是要准确地分析出系统应用者的需要,以及系统目标必须具备哪些功能。这些功能必须准确
地,完整地体现出用户的要求。
1.1软件功能需求分析
通过对用户需求的市场调查的分析,确定反应用户需求的系统逻辑模型,把整个设计划分成3个单元,分别是程序启动、用户界面、后台服务。使用Android和java编程语言及网络数据库相结合,编写一个基于android端的移动聊天系统软件。这个系统提供多个用户及时并发通信的平台。未注册用户可以注册成系统成员,已注册用户可以通过登录进入聊天系统。在系统中用户可以选择与某一个用户聊天,用户可以查找好友或附近的人,可以添加好友或把好友加黑名单等。 用户注册 :用户在注册界面填入相关正确信息后,后台对其进行处理。 用户登录:用户输入自己的QQ帐号及密码后,点击登录,后台对其进行验
证,以及好友的查找,登录成功后返回该用户的会话界面。
聊天:用户选定聊天对象后,对其发送信息,信息将由后台转发给选定的聊
天对象,进行,提示,显示。
后台运行 用户可以退出主界面,将聊天软件在后台运行,当有消息传入时,
消息会用广播的形势显示。 后台管理:对用户的管理。
1.2 安全需求分析
由于Android系统自身具备的开放源码的特征,它的安全性能成为信息安全领域研究的一个重要课题。Android的安全性能主要体现在两个方面:Android的系统安全和数据安全。Android系统安全是指智能终端本身的安全,是对操作系统的保护,防止未授权的访问及对授权用户服务的拒绝或对未授权用户服务的允许,包括行为检测、记录等措施。Android的数据安全指确保存储数据完整性、合法性二个方面,要求做到系统正确地传输数据,授权程序顺利地读取数据。
Android安全中的一个重要的设计点是在默认的情况下应用没有权限执行对其他应用程序、操作系统或用户的有害操作,这些操作包括读取用户的隐私数据,访问网络,保持设备活动等等,应用程序的进程是一个安全的黑盒子,在没
有给它权限的时候它不能干扰其他应用程序。
二.总体设计
系统采用流行的C/S结构模式。系统的分析设计采用面向对象的技术,应用Visio等工具进行辅助设计。
2.1 软件结构图
图2.1 软件结构图
2.2 功能描述
进入该软件,进入登录界面,如果没有账号,则可以点击立即注册,进入注册界面进行注册,登录进入主界面,显示会话、联系人、设置,通过选择相应菜单进行相关操作。
2.2.1注册功能概要
输入注册需要的信息,且保证正确 参与者:用户 执行者:用户
前提条件:开启程序,进入注册界面
用户注册流程图:
图2.2.1 用户注册流程图
2.2.2登录功能概要 判断输入信息格式 服务器验证输入信息 跳转进入好友列表界面 登录流程图:
仿QQ5.0侧滑(基于ViewDragHelper实现)
仿QQ5.0侧滑(基于ViewDragHelper实
现
)
①自定义控件SlidingMenu继承FrameLayout,放在FrameLayout上面的布局一层叠着者一层,通过getChildAt()可以很方便的获取到任意一层,进而控制此布局的变化。
public class SlidingMenu extends FrameLayout {
private ViewDragHelper mViewDragHelper;
private int mHeight;// 当前控件的高度
private int mWidhth;// 当前控件的宽度
private int mRange; // 菜单移动的距离
private ViewGroup mMenu;// 菜单内容
private ViewGroup mContent; // 主页面内容
private boolean isOpen = false;// 判断是否打开菜单
public SlidingMenu(Context context) {
this(context, null);
}
public SlidingMenu(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr);
// 初始化ViewDragHelper
mViewDragHelper = ViewDragHelper.create(this, callback);
}
}
②接下来我们在布局文件中使用我们自定的SlidingMenu,根据布局,我们一步一步实现SlidingMenu.
<?xml version="1.0" encoding="utf-8"?>
<com.yitong.myslidingmenu2.view.SlidingMenu
xmlns:android="
xmlns:tools="
android:id="@+id/main_slidingMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/bg"
android:orientation="horizontal"
tools:context="com.yitong.myslidingmenu2.MainActivity">
<include layout="@layout/left_menu"/>
<LinearLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/qq"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="click"
android:text="切换菜单"/>
</LinearLayout>
</com.yitong.myslidingmenu2.view.SlidingMenu>
③如果想实现侧滑,自定义控件中必须包含两个布局,在我们的SlidingMenu中的onFinishInflate方法中加以判断,并且获取菜单和主页面。在onSizeChanged获取到菜单滑出的宽和高。
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if (getChildCount() < 2) {
throw new IllegalStateException("使用SlidingMenu中必须包含两个View"); }
if (!(getChildAt(0) instanceof ViewGroup && getChildAt(1) instanceof ViewGroup)) { throw new IllegalStateException("子View必须是ViewGroup的子类");
}
mMenu = (ViewGroup) getChildAt(0);
mContent = (ViewGroup) getChildAt(1);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mHeight = getMeasuredHeight();
mWidhth = getMeasuredWidth();
mRange = (int) (mWidhth * 0.8);
}
④使用ViewDragHelper,需要把当前控件的时间交给ViewDragHelper处理。
@Override
public boolean onInterceptHoverEvent(MotionEvent event) {
// 把触摸事件传递给ViewDragHelper
return mViewDragHelper.shouldInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
try {
mViewDragHelper.processTouchEvent(event);// 让ViewDrageHelper处理触摸事件 } catch (Exception e) {
e.printStackTrace();
}
return true;
}
⑤ViewDragHelper的关键代码
private Callback callback = new Callback() {
@Override
public boolean tryCaptureView(View child, int pointerId) {
return true;// child:当前被拖拽的view.返回true表示当前view可以被拖拽 }
@Override
public int getViewHorizontalDragRange(View child) {
return mRange;// 返回拖拽的距离,并不对拖拽进行限制,决定了动画的执行速度 }
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) { // 根据建议值,修订水平方向移动的距离
if (child == mContent) { // ①滑动主页面内容,当超过屏幕预留宽度时,不再滑动。②向左滑动不能为负
left = fixContentSlidRange(left);
}
return left;
}
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {// 当View的位置改变时调用,可以在此方法中添加一些View特效
super.onViewPositionChanged(changedView, left, top, dx, dy);
// 当我们滑动菜单内容时,保持菜单内容不动,转化为主页面内容移动 int moveContentLeft = left;// 主页面内容左边的距离
if (changedView == mMenu) {
moveContentLeft = mContent.getLeft() + left;
mMenu.layout(0, 0, mMenu.getHeight(), mMenu.getHeight());// 强制菜单不移动 }
moveContentLeft = fixContentSlidRange(moveContentLeft);
mContent.layout(moveContentLeft, 0, moveContentLeft + mContent.getWidth(), mContent.getHeight());
animShow(moveContentLeft);// 菜单打开时,一些动画
invalidate();// 重绘界面,兼容低版本{android仿qq发表说说}.
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {// 当view松手时触发,处理自动平滑动画
super.onViewReleased(releasedChild, xvel, yvel);
if (xvel > 0) { // 水平速度+
open();
} else if (xvel == 0 && mContent.getLeft() > mRange / 2.0f) { // 手指在菜单滑出一半多时抬起
open();
} else {
close();
}
}{android仿qq发表说说}.
};
/**
* 修订主页面的滑动距离
*/
private int fixContentSlidRange(int left) {
if (left > mRange) {
return mRange;
} else if (left < 0) {
return 0;
}
return left;
}
/** 伴随动画 */
private void animShow(int moveContentLeft) {
float percent = moveContentLeft * 1.0f / mRange;// 0~1
/**
* 分析:
* 菜单区域:位移动画,缩放动画,渐变动画
* 内容区域:缩放动画
* 背景区域:亮度变化
*/
ViewHelper.setTranslationX(mMenu, evaluate(percent, -mRange / 1.2f, 0));// 位移动画 ViewHelper.setScaleX(mMenu, evaluate(percent, 0.6f, 1.0f));// 缩放动画
ViewHelper.setScaleY(mMenu, evaluate(percent, 0.6f, 1.0f));
ViewHelper.setAlpha(mMenu, evaluate(percent, 0.1f, 1.0f));// 渐变动画
ViewHelper.setPivotX(mContent, 0);// 缩放中心
ViewHelper.setPivotY(mContent, mHeight / 2);
ViewHelper.setScaleX(mContent, evaluate(percent, 1.0f, 0.9f));// 缩放动画
ViewHelper.setScaleY(mContent, evaluate(percent, 1.0f, 0.9f));
getBackground().setColorFilter((Integer)(colorEvaluate(percent, Color.BLACK, Color.TRANSPARENT)), PorterDuff.Mode.SRC_OVER);// 亮度变化
}
Android模仿QQ的左右滑动切换界面和下拉更新的效果
Android模仿QQ的左右滑动切换界面和下拉更新的效果
因为功能还没有完全实现,所以效果不是太好,不过呢,还是能实现,左右滑动时候切换界面和显示QQ好友列表的简单功能!!好了,废话不多说了看看实现的过程吧!
1.首先看看布局
主布局main.xml 1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:Android="
3. android:layout_width="fill_parent"
4. android:layout_height="fill_parent"
5. android:orientation="vertical" >
6.
7. <HorizontalScrollView{android仿qq发表说说}.
8. android:id="@+id/horizontalscrollview"
9. android:layout_width="match_parent"
10. android:layout_height="wrap_content"
11. android:background="@drawable/item"
12. android:fadingEdge="@null"
13. android:scrollbars="none" >
14.
15. <LinearLayout
16. android:id="@+id/linearlayout"
17. android:layout_width="match_parent"
18. android:layout_height="match_parent"
19. android:orientation="horizontal"
20. >
21. </LinearLayout>
22. </HorizontalScrollView>
23.
24. <android.support.v4.view.ViewPager
25. android:id="@+id/viewpaper"
26. android:layout_width="fill_parent"
27. android:layout_height="match_parent"
28. android:layout_weight="1" >
29. </android.support.v4.view.ViewPager>
31. </LinearLayout>
2,接着看看QQonline.xml 1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="
3. android:layout_width="fill_parent"
4. android:layout_height="fill_parent"
5. android:orientation="vertical"
6. android:background="@drawable/image2">
7.
8.
9. <ExpandableListView
10. android:id="@+id/elistview"
11. android:layout_width="fill_parent"
12. android:layout_height="wrap_content"
13. android:layout_marginLeft="5dp"
14.
15.
16. />
17.
18. </LinearLayout>
3.接着看看下拉更新的布局pullrefresh.xml
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="
3. android:layout_width="fill_parent"
4. android:layout_height="fill_parent"
5. android:background="@drawable/image1"
6. android:orientation="vertical" >
7.
8. <com.wang.pullrefresh.MyListView
9. android:id="@+id/listView"
10. android:layout_width="fill_parent"
11. android:layout_height="fill_parent" />
13.
14. </LinearLayout>
4.下拉更新过程实现的布局refresh.xml 1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="
3. android:layout_width="fill_parent"
4. android:layout_height="wrap_content" >
5.
6. <RelativeLayout
7. android:id="@+id/head_contentLayout"
8. android:layout_width="fill_parent"
9. android:layout_height="wrap_content"
10. android:paddingLeft="30dp" >
11.
12. <FrameLayout
13. android:layout_width="wrap_content"
14. android:layout_height="wrap_content"
15. android:layout_alignParentLeft="true"
16. android:layout_centerVertical="true" >
17.
18. <ImageView
19. android:id="@+id/head_arrowImageView"
20. android:layout_width="wrap_content"
21. android:layout_height="wrap_content"
22. android:layout_gravity="center"
23. android:src="@drawable/down" />
24.
25. <ProgressBar
26. android:id="@+id/head_progressBar"
27. style="?android:attr/progressBarStyleSmall"
28. android:layout_width="wrap_content"
29. android:layout_height="wrap_content"
30. android:layout_gravity="center"
31. android:visibility="gone" />
32. </FrameLayout>
33.
34. <LinearLayout
35. android:layout_width="wrap_content"
36. android:layout_height="wrap_content"
37. android:layout_centerHorizontal="true"
38. android:gravity="center_horizontal"
39. android:orientation="vertical" >
40.
41. <TextView 42. android:id="@+id/head_tipsTextView"
43. android:layout_width="wrap_content"
44. android:layout_height="wrap_content"
45. android:text="下拉可以刷新"
46. android:textSize="15dp" />
47.
48. <TextView
49. android:id="@+id/head_lastUpdatedTextView"
50. android:layout_width="wrap_content"
51. android:layout_height="wrap_content"
52. android:text="上次更新时间:"
53. android:textSize="12dp" />
54. </LinearLayout>
55. </RelativeLayout>
56.
57. </LinearLayout>
5.下拉更新的列表显示的布局list_item.xml
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="
3. android:layout_width="match_parent"
4. android:layout_height="wrap_content"
5. android:gravity="center_vertical"
6. android:orientation="horizontal" >
7.
8. <ImageView
9. android:id="@+id/imageView_item"
10. android:layout_width="60dp"
11. android:layout_height="60dp"
12. android:layout_marginLeft="5dp"
13. android:src="@drawable/qq" />
14.
15. <TextView
16. android:id="@+id/textView_item"{android仿qq发表说说}.
17. android:layout_width="wrap_content"
18. android:layout_height="wrap_content"
19. android:layout_marginLeft="10dp"
20. android:textColor="#FFFFFF"
21. />
22.
23. </LinearLayout>
6.接着看看还没有完善的QQ聊天信息的布局main3.xml
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="
3. android:layout_width="fill_parent"
4. android:layout_height="fill_parent"
5. android:orientation="vertical"
6. android:background="@drawable/image3">
7.
8.
9.
10. </LinearLayout>