Android - 应用程序信息的flags,系统应用与用户应用,onScrollListener,PopupWindow,View在Window中的位置

转载请注明出处:https://blog.csdn.net/mythmayor/article/details/72900243

1.应用程序信息的flags

  1. int flags = packageInfo.applicationInfo.flags
  2. 0000 0000 0000 0000 0000 0000 0000 0000 //int的32位每一位的0或者1表示一个boolean值
  3. 适用于需要大量boolean变量的场景,提高效率
  4. 具体代码

    int flags = packInfo.applicationInfo.flags;  
    if ((flags & ApplicationInfo.FLAG_SYSTEM) != 0) {  
        //系统应用  
    } else {  
        //用户应用  
    }  
    if ((flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {  
        //安装在sd卡  
    } else {  
        //安装在手机内存  
    }
    

2.应用的安装位置

<manifest 
    ...                           SD卡           手机内存     手机内存
    android:installLocation="preferExternal | internalOnly | auto"
/>

3.如何区分显示系统应用和用户应用

  1. 将“应用程序集合”拆分成“用户程序集合”和“系统程序集合”两个集合
  2. 在getView方法中,根据position判断,该位置应该是用户程序还是系统程序,在从对应的集合中取出数据
  3. 注意,当显示第二个集合的数据时,需要对position进行修正

4.将标签加入到ListView的item中显示

  1. 在getCount中计算出正确的个数:用户程序个数+系统程序个数+标签个数
  2. 在getView中,根据position判断需要显示的四种类型:用户程序标签、用户程序、系统程序标签、系统程序,根据不同的类型返回不同的view
  3. 注意,标签是插在列表的前面和中间,需要对position进行修正

5.ListView的item具有多种布局

当我们在Adapter中调用方法getView的时候,如果整个列表中的Item View如果有多种类型布局,如:

我们继续使用convertView来将数据从新填充貌似不可行了,因为每次返回的convertView类型都不一样,无法重用。

Android在设计上的时候,也想到了这点。所以,在adapter中预留的两个方法。

public int getViewTypeCount();              //有多少种布局类型  
public int getItemViewType(int position);   //获取某个位置是哪种类型类型

只需要重写这两个方法,设置一下ItemViewType的个数和判断方法,Recycler就能有选择性的给出不同的convertView了。

private static final int TYPE_LABEL = 0;
private static final int TYPE_CONTENT = 1;

private class AppManagerAdapter extends BaseAdapter{

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        if(position == 0 || position == userAappInfos.size()+1){
            return TYPE_LABEL;
        }else{
            return TYPE_CONTENT;
        }
    }

    /**
     * 返回listview里面有多少个条目
     */
    @Override
    public int getCount() {
        //为什么要加两个1 , 增加了两个textview的标签。整个listview条目的个数增加了。
        return 1+userAappInfos.size()+1+systemAppInfos.size();
    }

    /**
     * 显示每个条目的view对象
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LabelViewHolder labelViewHolder = null;
        ContentViewHolder contentViewHolder = null;

        int type = getItemViewType(position);
        if(convertView == null){
            switch (type) {
            case TYPE_LABEL:
                convertView = new TextView(AppManagerActivity.this);
                labelViewHolder = new LabelViewHolder();
                labelViewHolder.tv_label = (TextView) convertView;
                labelViewHolder.tv_label.setBackgroundColor(Color.GRAY);
                convertView.setTag(labelViewHolder);
                break;
            case TYPE_CONTENT:
                convertView = View.inflate(getApplicationContext(), R.layout.item_appinfo, null);
                contentViewHolder = new ContentViewHolder();
                contentViewHolder.iv_appIcon = (ImageView) convertView.findViewById(R.id.iv_appicon);
                contentViewHolder.tv_appName = (TextView) convertView.findViewById(R.id.tv_appName);
                contentViewHolder.tv_apkSize = (TextView) convertView.findViewById(R.id.tv_apkSize);
                contentViewHolder.iv_install_location = (ImageView) convertView.findViewById(R.id.iv_install_location);
                convertView.setTag(contentViewHolder);
                break;
            }
        }else{
            switch (type) {
            case TYPE_LABEL:
                labelViewHolder = (LabelViewHolder) convertView.getTag();
                break;
            case TYPE_CONTENT:
                contentViewHolder = (ContentViewHolder) convertView.getTag();
                break;
            }
        }

        switch (type) {
        case TYPE_LABEL:
            if(position == 0){
                labelViewHolder.tv_label.setText("用户程序:"+userAappInfos.size());
            }else{
                labelViewHolder.tv_label.setText("系统程序:"+systemAppInfos.size());
            }
            break;
        case TYPE_CONTENT:
            AppInfo appInfo;
            if(position<=userAappInfos.size()){//用户程序
                int newPosition = position - 1;//减去用户的标签textview占据的位置
                appInfo = userAappInfos.get(newPosition);
            }else {//系统程序
                int newPosition = position - 1 - userAappInfos.size() - 1;
                appInfo = systemAppInfos.get(newPosition);
            }

            contentViewHolder.iv_appIcon.setImageDrawable(appInfo.getAppIcon());
            contentViewHolder.tv_appName.setText(appInfo.getAppName());
            contentViewHolder.tv_apkSize.setText("程序大小:"+Formatter.formatFileSize(getApplicationContext(), appInfo.getAppSize()));
            if(appInfo.isInRom()){
                contentViewHolder.iv_install_location.setImageResource(R.drawable.memory);
            }else{
                contentViewHolder.iv_install_location.setImageResource(R.drawable.sd);
            }
            break;
        }

        return convertView;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }
}

/**
 * 存放内容孩子对象的引用
 */
static class ContentViewHolder{
    ImageView iv_appIcon;
    TextView tv_appName;
    TextView tv_apkSize;
    ImageView iv_install_location;
}

/**
 * 存放标签孩子对象的引用
 */
static class LabelViewHolder{
    TextView tv_label;
} 

6.ListView的OnScrollListener–滑动监听器

public static int SCROLL_STATE_IDLE = 0;            //停止
public static int SCROLL_STATE_TOUCH_SCROLL = 1;    //手指拖动
public static int SCROLL_STATE_FLING = 2;           //惯性滑动

listView.setonScrollListener(new OnScrollListener() {

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        //滚动状态发生变化。0停止,1手指拖动,2惯性滑动
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
        //当listview正在滚动的时候调用的方法
        //firstVisibleItem:第一个显示的Item的位置
        //visibleItemCount:可显示的Item的总数
        //totalItemCount:Item的总数
    }
});

7.PopupWindow的使用

//创建,指定显示的View和宽高
PopupWindow ppw = new PopupWindow(View contentView, int width, int height);
//显示,parent并不是指要把contentView 添加到parent上,而是要获取token
ppw. showAtLocation(View parent, int gravity, int x, int y);
//关闭
ppw. dismiss(); 

8.PopupWindow使用注意事项

1.在show之前dismiss掉之前创建的,避免重复显示
2.在Activity的onDestory()的时候dismiss,避免窗体泄漏

9.获取View在Window中的位置

int[] location = new int[2];
view.getLocationInWindow(location);
Location[0]: x坐标
Location[1]: y坐标

获取View在父View中的位置
view.getX();
view.getY();

10.PopupWindow不显示动画的原因

1.手机中设置了动画关闭
2.PopupWindow没有设置背景

注:PopupWindow要设置背景和获取焦点,才能有点击弹框外消失的效果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值