当前位置:  编程技术>移动开发
本页文章导读:
    ▪自定义组件—ListView_添头去头,加脚去脚、添加或删除ListView中的数据        自定义组件—ListView_加头去头,加脚去脚、添加或删除ListView中的数据、 注:该文章为(男人应似海)原创,如需转载请注明出处! 该组件的功能有三个: (1)       任意加头去头,.........
    ▪ 批量装配于卸载        批量安装于卸载有尝试过在Android手机里批量安装于批量卸载你的应用程序吗,现在就简单教你怎么做,其实很简单,还有后台安装于卸载问题: 1.后台安装于卸载步骤: 首先你需要使用其Pm.........
    ▪ ICSLauncher改建-替换滑屏Indicator       ICSLauncher改造-替换滑屏Indicator背景: 原生ICS 已经有一种通过9patch拉伸实现的scrollIndicator但是不够美观,本文就在不修改原生scrollindicator的基础上添加新的冒泡scrollindicator。 效果图如下。实.........

[1]自定义组件—ListView_添头去头,加脚去脚、添加或删除ListView中的数据
    来源: 互联网  发布时间: 2014-02-18
自定义组件—ListView_加头去头,加脚去脚、添加或删除ListView中的数据、

注:该文章为(男人应似海)原创,如需转载请注明出处!

该组件的功能有三个:

(1)       任意加头去头,加脚去脚。

我们知道ListView在setAdapter之后再调用addHeader方法会抛出异常,而加脚有时管用,有时不管用。Android开发文档中也明确指出ListView在setAdapter之后不应该再进行setHeader和setFooter方法。这明显不能满足我们的实际需求。

我的是:在setAdapter之前给ListView先加上一个空头布局和空脚布局,布局高度设为wrap_content,这样当头或脚布局中没有任何组件时,头和脚是看不到的。当需要显示头和脚时,直接向头和脚布局中添加要显示的组件即可。

(2)       可任意添加或删除ListView中的数据。

有过实际开发经验的同学可能会有所体会,我们每次改变数据后都要调一次adapter.notifyDataSetChanged(),而且当ListView添加或删除数据的操作未完成时,再来一次添加或删除数据操作的话会报异常。比如用ListView显示网络获取的数据时,不断的刷新数据就会出现这种情况。这时候“同步“获取数据的线程是无法避免这个问题的,因为当线程获取网络数据特别快时还是会出现Listview添加数据操作的同时发生。

我的解决办法是:在该组件中自己实现添加和删除数据的方法并用一个变量来标记当前ListView是否在进行添加或删除数据操作,是的话则不允许在进行数据操作。

(3)       实现了向下滑动出现一个显示正在加载的头布局,手离开屏幕时头布局自动隐藏的功能。如YiBo微博首页的下拉刷新效果。效果图如下:

      

 

拉动前图片

按下拉动后图片

代码:

package diy.ts.wader.widget;

 

import java.util.Collection;

import java.util.List;

 

import android.content.Context;

import android.graphics.Color;

import android.util.AttributeSet;

import android.view.Gravity;

import android.view.MotionEvent;

import android.view.View;

import android.widget.BaseAdapter;

import android.widget.LinearLayout;

import android.widget.ListView;

import android.widget.ProgressBar;

import android.widget.TextView;

 

/******************************************************************

 * 文件名称 : MyListView.java

 * 作者 : wader

 * 创建时间 : 2011-7-20上午10:40:05

 * 文件描述 :

 * 实现了下拉显示组件头、任意添加头脚、添加删除数据功能的ListView组件

 ******************************************************************/

public class MyListView extends ListView {

    private BaseAdapter adapter;

    private List<Object> dataList;

    private Context context;

    private LinearLayout header;

    private LinearLayout footer;

    /*

     * 在touch时间后的move动作时显示的头部动画

     */

    private LinearLayout headerContent;

    ProgressBar headerProgressBar;

    TextView headertextView;

 

    private OnHeadShowOrHideAcion onHeadShowOrHideAcion = null;

    /*

     * 在init时是否加头布局,在init方法前设置

     */

    private boolean addHeader = false;

    /*

     * 在init时是否加脚布局,在init方法前设置

     */

    private boolean addFooter = false;

    /*

     * 在touch时间后的move动作时是否显示头部动画

     */

    private boolean showAnimationHead = false;

    /*

     * 在显示头部动画时是否执行HeadShowOrHideAcion的doActionOnShowHead方法

     */

    private boolean doActionOnShowHead = true;

    /*

     * 在显示头部动画时是否执行HeadShowOrHideAcion的doActionOnHideHead方法

     */

    private boolean doActionOnHideHead = true;

    /*

     * 头布局中是否已有内容(headerContent!=null)并已显示出来

     */

    private boolean haveHead = false;

    /*

     * 是否可以对list进行添加或删除数据操作,保证list数据同步

     */

    private boolean ableOperateData = true;

    private float initY = 0;

 

    public MyListView(Context context) {

       super(context);

    }

 

    public MyListView(Context context, AttributeSet attrs) {

       this(context, attrs, 0);

    }

 

    public MyListView(Context context, AttributeSet attrs, int defStyle) {

       super(context, attrs, defStyle);

    }

 

    /*

     * 设置在init时是否加头布局,在init方法前设置

     */

    public void setAddHeader(boolean addHeader) {

       this.addHeader = addHeader;

    }

 

    /*

     * 设置在init时是否加脚布局,在init方法前设置

     */

    public void setAddFooter(boolean addFooter) {

       this.addFooter = addFooter;

    }

 

    /*

     * 设置在touch时间后的move动作时是否显示头部动画

     */

    public void setShowAnimationHead(boolean param) {

       this.showAnimationHead = param;

    }

 

    /*

     * 设置在显示头部动画时是否执行HeadShowOrHideAcion的doActionOnShowHead方法

     */

    public void setDoActionOnShowHead(boolean param) {

       this.doActionOnShowHead = param;

    }

 

    /*

     * 设置在隐藏头部动画时是否执行HeadShowOrHideAcion的doActionOnHideHead方法

     */

    public void setDoActionOnHideHead(boolean param) {

       this.doActionOnHideHead = param;

    }

 

    /*

     * 对listview进行初始化,在使用该组件前必须先执行这个方法

     */

    public void init(Context context) {

       this.context = context;

       this.addHeaderAndFooterLayout();

    }

 

    /*

     * 加头布局和脚布局

     */

    private void addHeaderAndFooterLayout() {

       if (addHeader) {

           header = new LinearLayout(context);

           addHeaderView(header);

           header.setVisibility(View.GONE);

       }

       if (addFooter) {

           footer = new LinearLayout(context);

           addFooterView(footer);

           footer.setVisibility(View.GONE);

       }

    }

 

    /*

     * 显示指定的头内容

     */

    public void showHeader(View view) {

       if (view.getLayoutParams() == null) {

           view.setLayoutParams(new LinearLayout.LayoutParams(

                  LinearLayout.LayoutParams.WRAP_CONTENT,

                  LinearLayout.LayoutParams.WRAP_CONTENT));

       }

       header.setVisibility(View.VISIBLE);

       if (header.getChildCount() <= 0)

           header.addView(view);

       this.postInvalidate();

    }

 

    /*

     * 显示指定的头动画

     */

    public void showAnimationHeader() {

       if (!haveHead && addHeader) {

           if (headerContent == null) {

              headerContent = new LinearLayout(context);

              headerContent.setLayoutParams(new LinearLayout.LayoutParams(

                     LinearLayout.LayoutParams.FILL_PARENT,

                     LinearLayout.LayoutParams.FILL_PARENT));

              headerContent.setBackgroundColor(Color.LTGRAY);

              headerContent.setGravity(Gravity.CENTER);

              headerContent.setOrientation(LinearLayout.HORIZONTAL);

 

           } else

              headerContent.removeAllViews();

           if (headertextView == null) {

              headertextView = new TextView(context);

              headertextView.setTextColor(Color.BLACK);

              headertextView.setTextSize(20);

              headertextView.setText("松开即可更新");

           }

           headerProgressBar = new ProgressBar(context);

           headerProgressBar.setPadding(0, 3, 20, 3);

           headerContent.addView(headerProgressBar);

           headerContent.addView(headertextView);

 

           this.showHeader(headerContent);

           haveHead = true;

           if (onHeadShowOrHideAcion != null && doActionOnShowHead) {

              doActionOnShowHead = false;

              onHeadShowOrHideAcion.doActionOnShowHead(this);

           }

       }

    }

 

    /*

     * 删除头内容

     */

    public void hideHeader() {

       if (addHeader) {

           header.removeAllViews();

           haveHead = false;

           header.setVisibility(View.GONE);

           this.postInvalidate();

           if (onHeadShowOrHideAcion != null && doActionOnHideHead)

              onHeadShowOrHideAcion.doActionOnHideHead(this);

       }

    }

 

    /*

     * 显示指定的脚内容

     */

    public void showFooter(View view) {

       if (addFooter) {

           if (view.getLayoutParams() == null) {

              view.setLayoutParams(new LinearLayout.LayoutParams(

                     LinearLayout.LayoutParams.WRAP_CONTENT,

                     LinearLayout.LayoutParams.WRAP_CONTENT));

           }

           footer.setVisibility(View.VISIBLE);

           if (footer.getChildCount() <= 0)

              footer.addView(view);

           this.postInvalidate();

           this.postInvalidate();

       }

    }

 

    /*

     * 删除脚内容

     */

    public void hideFooter(View view) {

       if (addFooter) {

           footer.removeAllViews();

           footer.setVisibility(View.GONE);

           this.postInvalidate();

       }

    }

 

    /*

     * 为listview设置adapter和与该adapter相关的list,应该在init方法之后执行

     */

    @SuppressWarnings("unchecked")

    public void setData(BaseAdapter adapter, List<? extends Object> dataList) {

       this.adapter = adapter;

       this.dataList = (List<Object>) dataList;

       setAdapter(adapter);

    }

 

    /*

     * 在list最后添加新数据

     */

    public void addData(Collection<? extends Object> c) {

       if (ableOperateData) {

           ableOperateData = false;

           if (dataList == null || adapter == null)

              throw new NullPointerException(

                     "You do not call the setData() method");

           dataList.addAll(c);

           adapter.notifyDataSetChanged();

       }

       ableOperateData = true;

    }

 

    /*

     * 在list的指定位置添加新数据

     */

    public void addData(int index, Collection<? extends Object> c) {

       if (ableOperateData) {

           ableOperateData = false;

           if (dataList == null || adapter == null)

              throw new NullPointerException(

                     "You don not call the setData() method or the Adapter or List param in setData() is null");

           dataList.addAll(index, c);

           adapter.notifyDataSetChanged();

       }

       ableOperateData = true;

    }

 

    /*

     * 删除list中指定位置的数据

     */

    public void deleteData(int index) {

       if (ableOperateData) {

           ableOperateData = false;

           dataList.remove(index);

           adapter.notifyDataSetChanged();

       }

       ableOperateData = true;

    }

 

    /*

     * 删除list中的全部数据

     */

    public void deleteAll() {

       if (ableOperateData) {

           ableOperateData = false;

           dataList.clear();

           adapter.notifyDataSetChanged();

       }

       ableOperateData = true;

    }

 

    /*

     * 触屏事件,主要是为了显示头动画

     */

    public void touchEventAction(MotionEvent ev) {

       switch (ev.getAction()) {

       case MotionEvent.ACTION_MOVE:

           if (this.getFirstVisiblePosition() == 0 && (ev.getY() - initY > 30)

                  && !haveHead) {// 当向下滑动30个单位时显示头部动画

              showAnimationHeader();

 

           }

           break;

       case MotionEvent.ACTION_UP:

           hideHeader();

           break;

       case MotionEvent.ACTION_DOWN:

           initY = ev.getY();

           break;

       }

    }

 

    @Override

    public boolean dispatchTouchEvent(MotionEvent ev) {

       if (showAnimationHead)

           this.touchEventAction(ev);

       super.dispatchTouchEvent(ev);

       return true;

    }

 

    /*

     * 设置在显示头部动画时要执行HeadShowOrHideAcion

     */

    public void setHeadShowOrHideAcion(

           OnHeadShowOrHideAcion paramOnHeadShowOrHideAcion) {

       this.onHeadShowOrHideAcion = paramOnHeadShowOrHideAcion;

    }

 

    /*

     * 自定义内部接口

     */

    public abstract interface OnHeadShowOrHideAcion {

       public void doActionOnShowHead(ListView paramListView);

 

       public void doActionOnHideHead(ListView paramListView);

    }

}

 

  注:

    (1)OnHeadShowOrHideAcion接口是为了实现当下拉刷新时要进行的操作,如启动线程获取网络数据。

         (2)ListView加头布局后item下标是从1开始而不是从0开始。

         (3)该组件用起来可能比较麻烦,大家可以根据自身需要对它进行瘦身和改造。


    
[2] 批量装配于卸载
    来源: 互联网  发布时间: 2014-02-18
批量安装于卸载

有尝试过在Android手机里批量安装于批量卸载你的应用程序吗,现在就简单教你怎么做,其实很简单,还有后台安装于卸载问题:

1.后台安装于卸载步骤:

首先你需要使用其Pm命令,如一下

  • pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH  
  • pm uninstall [-k] PACKAGE 
  • 代码实现也很简单,使用流的方式来进行相关操作:

  • public static void execCommand(String... command) {  
  • 02      Process process = null;  
  • 03      try {  
  • 04          process = new ProcessBuilder().command(command).start();  
  • 05          //对于命令的执行结果我们可以通过流来读取  
  • 06          // InputStream in = process.getInputStream();  
  • 07          // OutputStream out = process.getOutputStream();  
  • 08          // InputStream err = process.getErrorStream();  
  • 09      } catch (IOException e) {  
  • 10          e.printStackTrace();  
  • 11      } finally {  
  • 12          if (process != null)  
  • 13              process.destroy();  
  • 14      }  
  • 15  }  
  •    
  • 1   execCommand("pm", "install", "-f", filePath);//安装apk,filePath为apk文件路径,如/mnt/sdcard/ApiDemos.apk  
  • 2   execCommand("pm", "uninstall", packageName);//卸载apk,packageName为包名,如com.example.android.apis 
  • 注意一下:

  • 编译生成apk时,要在你的manifest文件下添加android:sharedUserId="android.uid.system",编译完成之后还无法正常安装,会出现Installation error: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE错误,此时,要为apk重新签名。  
  •   
  • 在android源码\build\target\product\security中找platform.pk8和platform.x509.pem两个文件,在android 编绎目录out下找到 signapk.jar 这个包(源码目录\build\tools\signapk),并把编译好的apk(如PMDemo.apk)放在同一目录下,在重新签名之前,用rar文件打开apk文件,进入META-INF目录下,将CERT.SF和CERT.RSA这两个文件删除掉,然后在命令行中执行以下命令:  
  •    
  • 1   java -jar signapk.jar platform.x509.pem platform.pk8 PMDemo.apk NewPMDemo.apk  
  • 安装前先把旧的apk卸载,这样重新签名之后的apk就可以正常安装了。   

  • 很简单吧,下面看下批量操作:

    直接看代码吧:

  • 通常情况下,android是没有提供静默方式的上层接口,我们需要在android源代码下来调用这个隐藏的接口来完成静默安装。  
  • 最重要的就是参考android系统目录下的packages/apps/PackageInstaller,  
  • 当中有两个文件 PackageInstallerActivity.java,InstallAppProgress.java ,前者就是我们通常看到的带有提示对话框的安装应用程序,后者是点确定安装后调用的intent。  
  • 现提供一个静默安装的关键类,该类在android2.2下成功编译, 其中通过循环调用接口instatllBatch则可实现批量安装  
  • 当然最后的应用程序别忘记添加权限  
  •   
  •     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
  •         <uses-permission android:name="android.permission.INSTALL_PACKAGES" />  
  •         <uses-permission android:name="android.permission.DELETE_PACKAGES" />  
  •         <uses-permission android:name="android.permission.CLEAR_APP_CACHE" />  
  •         <uses-permission android:name="android.permission.READ_PHONE_STATE" />  
  •         <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />  
  •   
  • package com.android.util;  
  •   
  • import java.io.File;    
  •   
  • import java.io.FileNotFoundException;    
  •   
  • import java.io.FileOutputStream;    
  •   
  • import java.io.IOException;    
  •   
  • import android.content.Context;    
  •   
  • import android.content.Intent;    
  •   
  • import android.content.pm.PackageInfo;    
  •   
  • import android.content.pm.PackageManager;    
  •   
  • import android.content.pm.PackageManager.NameNotFoundException;    
  •   
  • import android.content.pm.ApplicationInfo;  
  •   
  • import android.content.pm.PackageParser;  
  •   
  • import android.net.Uri;    
  •   
  • import android.util.Log;    
  •   
  • import android.util.DisplayMetrics;  
  •   
  • import android.content.pm.IPackageInstallObserver;    
  •   
  • import android.content.pm.IPackageDeleteObserver;    
  •   
  • import android.os.FileUtils;    
  •   
  • import android.os.Handler;  
  •   
  • import android.os.Message;  
  •   
  •    
  •   
  • public class PackageInstaller {    
  •   
  •    
  •   
  • private File mTmpFile;    
  •   
  • private final int INSTALL_COMPLETE = 1;  
  •   
  • final static int SUCCEEDED = 1;  
  •   
  • final static int FAILED = 0;  
  •   
  • private final static String TAG = "PackInstaller";    
  •   
  • private Context mContext;    
  •   
  • private ApplicationInfo mAppInfo;  
  •   
  • public PackageInstaller(Context context) {    
  •   
  • mContext = context;    
  •   
  • }    
  •   
  • public void install(String path,String packageName){    
  •   
  • Intent intent = new Intent(Intent.ACTION_VIEW);    
  •   
  • intent.setDataAndType(Uri.fromFile(new File(path)),    
  •   
  • "application/vnd.android.package-archive");    
  •   
  • mContext.startActivity(intent);    
  •   
  • }    
  •   
  •    
  •   
  • public void instatllBatch(String path) {    
  •   
  • Log.i(TAG, "path=" + path);    
  •   
  • int installFlags = 0;    
  •   
  • Uri mPackageURI  = Uri.fromFile(new File(path));  
  •   
  • PackageParser.Package mPkgInfo = getPackageInfo(mPackageURI);  
  •   
  • mAppInfo =  mPkgInfo.applicationInfo;  
  •   
  • String packageName = mAppInfo.packageName;  
  •   
  • Log.i(TAG, "====install packageName ="+packageName);  
  •   
  • PackageManager pm = mContext.getPackageManager();    
  •   
  • try {    
  •   
  • PackageInfo pi = pm.getPackageInfo(packageName,    
  •   
  • PackageManager.GET_UNINSTALLED_PACKAGES);    
  •   
  • if (pi != null) {    
  •   
  • installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;    
  •   
  • }    
  •   
  • } catch (NameNotFoundException e) {    
  •   
  • }    
  •   
  • if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {    
  •   
  • Log.w(TAG, "Replacing package:" + packageName);    
  •   
  • }    
  •   
  •    
  •   
  • PackageInstallObserver observer = new PackageInstallObserver();    
  •   
  • pm.installPackage(mPackageURI, observer, installFlags,    
  •   
  • packageName);    
  •   
  • }    
  •   
  • private class PackageInstallObserver extends IPackageInstallObserver.Stub {    
  •   
  • public void packageInstalled(String packageName, int returnCode) {    
  •   
  • // Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);    
  •   
  • // msg.arg1 = returnCode;    
  •   
  • // mHandler.sendMessage(msg);    
  •   
  • Log.i(TAG, "====INSTALL_COMPLETE");    
  •   
  • }    
  •   
  • }    
  •   
  • private class PackageDeleteObserver extends IPackageDeleteObserver.Stub {    
  •   
  • public void packageDeleted(boolean succeeded) {    
  •   
  • //            Message msg = mHandler.obtainMessage(UNINSTALL_COMPLETE);    
  •   
  • //            msg.arg1 = succeeded?SUCCEEDED:FAILED;    
  •   
  • //            mHandler.sendMessage(msg);    
  •   
  • Log.i(TAG, "====UNINSTALL_COMPLETE");    
  •   
  • }    
  •   
  • }    
  •   
  •     public void uninstall(String packageName){    
  •   
  • Uri packageURI = Uri.parse("package:" + packageName);    
  •   
  • Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,    
  •   
  • packageURI);    
  •   
  • mContext.startActivity(uninstallIntent);    
  •   
  • }    
  •   
  •    
  •   
  • public void uninstallBatch(String packageName) {    
  •   
  • PackageDeleteObserver observer = new PackageDeleteObserver();    
  •   
  • mContext.getPackageManager().deletePackage(packageName, observer, 0);    
  •   
  •    
  •   
  • }    
  •   
  • public  PackageParser.Package getPackageInfo(Uri packageURI) {  
  •   
  • final String archiveFilePath = packageURI.getPath();  
  •   
  • PackageParser packageParser = new PackageParser(archiveFilePath);  
  •   
  • File sourceFile = new File(archiveFilePath);  
  •   
  • DisplayMetrics metrics = new DisplayMetrics();  
  •   
  • metrics.setToDefaults();  
  •   
  • PackageParser.Package pkg =  packageParser.parsePackage(sourceFile,  
  •   
  • archiveFilePath, metrics, 0);   
  •   
  • // Nuke the parser reference.  
  •   
  • packageParser = null;  
  •   
  • return pkg;  
  •   
  • }  
  •   
  • public   ApplicationInfo getApplicationInfo(Uri packageURI) {  
  •   
  • final String archiveFilePath = packageURI.getPath();  
  •   
  • PackageParser packageParser = new PackageParser(archiveFilePath);  
  •   
  • File sourceFile = new File(archiveFilePath);  
  •   
  • DisplayMetrics metrics = new DisplayMetrics();  
  •   
  • metrics.setToDefaults();  
  •   
  • PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0);  
  •   
  • if (pkg == null) {  
  •   
  • return null;  
  •   
  • }  
  •   
  • return pkg.applicationInfo;  
  •   
  • }  
  •   
  • private Handler mHandler = new Handler() {  
  •   
  • public void handleMessage(Message msg) {  
  •   
  • switch (msg.what) {  
  •   
  • case INSTALL_COMPLETE:  
  •   
  • if(msg.arg1 == SUCCEEDED) {  
  •   
  •    
  •   
  • } else {}  
  •   
  • break;  
  •   
  • default:  
  •   
  • break;  
  •   
  • }  
  •   
  • }  
  •   
  • };  
  •   
  • }  

  •  


        
    [3] ICSLauncher改建-替换滑屏Indicator
        来源: 互联网  发布时间: 2014-02-18
    ICSLauncher改造-替换滑屏Indicator
    背景:

    原生ICS 已经有一种通过9patch拉伸实现的scrollIndicator但是不够美观,本文就在不修改原生scrollindicator的基础上添加新的冒泡scrollindicator。

    效果图如下。实现思路很简单,见正文。


    1.添加View对象 1.1 AppScreenBubbleViewFrameLayout extends FrameLayout
    每一个“点”是一个AppScreenBubbleViewFrameLayout,它有两个成员变量,imageViewFront、imageViewBack,当前页显示imageViewFront,其他页显示imageViewBack。
    1.2 AppScreenBubbleViewFrameLayout extends FrameLayout
              
     for (int page = 0; page < totalPages; ++page) {
                LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
                        LayoutParams.WRAP_CONTENT);
    
                AppScreenBubbleViewFrameLayout appScreenBubbleViewFrameLayout = new AppScreenBubbleViewFrameLayout(
                        mContext);
    
                if (page == mCurrentPage) {
                    appScreenBubbleViewFrameLayout.getImageViewFront()
                            .setImageDrawable(getFocusDrawable());
                }
                else {
                    appScreenBubbleViewFrameLayout.getImageViewFront()
                            .setImageDrawable(getNormalDrawable());
                }
    
                this.addView(appScreenBubbleViewFrameLayout, layoutParams);
            }

    1.2添加AppScreenBubbleViewFrameLayout布局文件
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    	xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
    	android:layout_width="fill_parent" android:layout_height="wrap_content"
    	android:scaleType="center" android:layout_gravity="bottom|center_horizontal"
    	launcher:direction="horizontal">
    	<com.android.launcher2.AppScreenBubbleView
    		android:id="@+id/drawer_appscreen_num" android:layout_width="match_parent"
    		android:layout_height="wrap_content" android:gravity="center_horizontal"/>
    </LinearLayout>



    2.合入Launcher 2.1在Laucher.xml中添加如下布局
        <!-- add bubble view -->
         <include layout="@layout/workspace_bubble_view_layout"
            android:id="@+id/bubbleView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:layout_marginBottom="@dimen/button_bar_height"/>
    2.2.在Laucher.java中初始化
          //add bubbleView to Workspace
           View bubbleView = mDragLayer.findViewById(R.id.bubbleView);
           mScreenBubbleView = (AppScreenBubbleView) bubbleView.findViewById(R.id.drawer_appscreen_num);
           mWorkspace.setAppScreenBubbleView(mScreenBubbleView);
           //mScreenBubbleView.show
           mWorkspace.showScreenBubbleView(false);

    3.PagedView
         注意学习动画得使用啊,亲!
    protected void showScreenBubbleView(boolean immediately){
            if (getChildCount() <= 1) return;
            if(!isScreenBubbleEnable()) return;
            getScreenBubbleView();
            if(mScreenBubbleView != null){
                updateScreenPosition();
                mScreenBubbleView.setVisibility(View.VISIBLE);
                if (immediately) {
                    mScreenBubbleView.setAlpha(1f);
                }
                else{
                    mScreenBubbleViewAnimator = ObjectAnimator.ofFloat(mScreenBubbleView, "alpha", 1f);
                    mScreenBubbleViewAnimator.setDuration(sScreenBubbleFadeInDuration);
                    mScreenBubbleViewAnimator.start();
                }
            }
        }
     // a method that subclasses can override to add behavior
        protected void onPageBeginMoving() {
            showScrollingIndicator(false);
            showScreenBubbleView(false);
        }



        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android开发之注册登录方法示例
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android根据电话号码获得联系人头像实例代码
    ▪Android中GPS定位的用法实例
    ▪Android实现退出时关闭所有Activity的方法
    ▪Android实现文件的分割和组装
    ▪Android录音应用实例教程
    ▪Android双击返回键退出程序的实现方法
    ▪Android实现侦听电池状态显示、电量及充电动...
    ▪Android获取当前已连接的wifi信号强度的方法
    ▪Android实现动态显示或隐藏密码输入框的内容
    ▪根据USER-AGENT判断手机类型并跳转到相应的app...
    ▪Android Touch事件分发过程详解
    ▪Android中实现为TextView添加多个可点击的文本
    ▪Android程序设计之AIDL实例详解
    ▪Android显式启动与隐式启动Activity的区别介绍
    ▪Android按钮单击事件的四种常用写法总结
    ▪Android消息处理机制Looper和Handler详解
    ▪Android实现Back功能代码片段总结
    ▪Android实用的代码片段 常用代码总结
    ▪Android实现弹出键盘的方法
    ▪Android中通过view方式获取当前Activity的屏幕截...
    ▪Android提高之自定义Menu(TabMenu)实现方法
    ▪Android提高之多方向抽屉实现方法
    ▪Android提高之MediaPlayer播放网络音频的实现方法...
    ▪Android提高之MediaPlayer播放网络视频的实现方法...
    ▪Android提高之手游转电视游戏的模拟操控
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3