开发小知识随手记

1.通过创建TaskStackBuilder 实现点击通知栏进入界面,界面点击返回键停留在APP而不返回桌面。

    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    //启动通知Activity时,拉起主页面Activity
    Intent msgIntent = new Intent();
    msgIntent.setClass(this, MessageActivity.class);

    //创建返回栈
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    //添加Activity到返回栈
    stackBuilder.addParentStack(MessageActivity.class);
    //添加Intent到栈顶
    stackBuilder.addNextIntent(msgIntent);

    PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

    // create and send notificaiton
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
            .setSmallIcon(getApplicationInfo().icon)
            .setWhen(System.currentTimeMillis())
            .setAutoCancel(true)//自己维护通知的消失
            .setContentTitle("我是标题")
            .setTicker("我是ticker")
            .setContentText("我是内容")
            .setContentIntent(pendingIntent);
    //将一个Notification变成悬挂式Notification
    mBuilder.setFullScreenIntent(pendingIntent, true);
    Notification notification = mBuilder.build();
    manager.notify(0, notification);
}

2.Google库中的类----可以轻松实现底部动作条功能(com.google.android.material.bottomsheet)

代码示例
//设置监听事件   
bottomSheetBehavior.setBottomSheetCallback(newBottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                //拖动 }
            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                //状态变化
            }
        })}

3.复杂布局点击状态变化和点击事件触发可借鉴写法
举个栗子:ImageView在上,TextView在下构成一个布局,点击呈现不同的文字和图片并处理点击事件,可将整个布局及其事件抽象为一个class,通过调用方法设置控件等
参考代码:

 keepScreenOnSetting = new SettingImageItem(view, context)
                .setEnabled(false)
                .setIcon(R.drawable.ic_btn_lock_off)
                .setSelectedIcon(R.drawable.ic_btn_lock)
                .setTitle(R.string.display_lock_off)
                .setSelectedTitle(R.string.display_lock_on)
                .setClickListener(new MyKeepScreenOnClickListener());

SettingImageItem.class:

 private class SettingImageItem {
        private ImageView icon;
        private ImageView mvpIcon;
        private TextView settingTitle;
        private View view;
        private boolean isSelected = false;
        private Context context;
        private int selectIconRes;
        private int iconRes;
        private int titleRes;
        private int selectedTitleRes;
        private boolean showPremiumUpsell = false;

        SettingImageItem(View root, Context context) {
            this.context = context;
            view = LayoutInflater.from(context).inflate(R.layout.record_setting_icon_item, (ViewGroup) root, false);
            icon = view.findViewById(R.id.icon);
            settingTitle = view.findViewById(R.id.icon_text);
            mvpIcon = view.findViewById(R.id.mvp_icon);
        }

        View getView() {
            return view;
        }

        void setSelected(boolean selected) {
            this.isSelected = selected;
            if (isSelected) {
                settingTitle.setTextColor(ContextCompat.getColor(context, R.color.bright_map_my_blue));
                icon.setBackgroundResource(selectIconRes);
                settingTitle.setText(selectedTitleRes);
            } else {
                settingTitle.setTextColor(ContextCompat.getColor(context, R.color.workoutSettingSubText));
                icon.setBackgroundResource(iconRes);
                settingTitle.setText(titleRes);
            }
        }

        SettingImageItem setEnabled(boolean value) {
            view.setClickable(value);
            return this;
        }

        SettingImageItem setShowPremiumUpsell(boolean value) {
            this.showPremiumUpsell = value;
            if (showPremiumUpsell) {
                mvpIcon.setVisibility(View.GONE);
            } else {
                mvpIcon.setVisibility(View.GONE);
            }
            return this;
        }

        SettingImageItem setIcon(int res) {
            this.iconRes = res;
            icon.setBackgroundResource(res);
            return this;
        }

        SettingImageItem setSelectedIcon(int res) {
            this.selectIconRes = res;
            return this;
        }

        SettingImageItem setTitle(int res) {
            this.titleRes = res;
            settingTitle.setText(res);
            return this;
        }

        SettingImageItem setSelectedTitle(int res) {
            this.selectedTitleRes = res;
            return this;
        }

        SettingImageItem setLiveTrackingClickListener(View.OnClickListener clickListener) {
            if (showPremiumUpsell) {
                view.setOnClickListener(new LiveTrackingUpsellClickListener());
            } else {
                view.setOnClickListener(clickListener);
            }
            return this;
        }

        SettingImageItem setClickListener(View.OnClickListener clickListener) {
            view.setOnClickListener(clickListener);
            return this;
        }

    }

3.android 自定义View 构造函数怎么样调用
首先自定义View有三个构造方法:
级联式调用,每一个构造函数调用比它多一个参数的构造函数,最后一个构造函数调用基类的构造函数,最后在做一些额外的初始化工作。

public class CustomView extends View { /**
     * 第一个构造函数
     * @param context
     */
    public CustomView(Context context) { super(context,null);
    } /**
     * 第二个构造函数
     * @param context
     * @param attrs
     */
    public CustomView(Context context, @Nullable AttributeSet attrs) { super(context, attrs,0);
    } /**
     * 第三个构造函数
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr);
        //获取自定义属性
    } @Override
    protected void onDraw(Canvas canvas) { super.onDraw(canvas);
    } }

在代码中的使用时机:

1.直接new一个实例的时候,会调用第一个构造函数

2.在xml布局文件调用的时候,会调用第二个构造函数

3.在xml布局文件中调用,并且标签中还有自定义属性时,这里调用的还是第二个构造函数

也就是说,系统默认只会调用前两个构造函数,至于第三个构造函数的调用,通常都是我们在构造函数中主动调用的。(例如,在第二个构造函数中调用第三个构造函数)
推荐使用:

ublic class CustomView extends View { /**
     * 在Java代码中直接new出来的时候调用
     * @param context
     */
    public CustomView(Context context) { super(context);
        initCustomView();
    } /**
     * 在XML中不使用自定义属性的时候调用
     * @param context
     * @param attrs
     */
    public CustomView(Context context, @Nullable AttributeSet attrs) { super(context, attrs);
        initCustomView();
    } /**
     * 在XML中使用自定义属性的时候调用
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr);
        initCustomView();
        //获取自定义属性
    }

此部分内容参考:原文:https://blog.csdn.net/Zophar_Development/article/details/80506341

4.对RecycleView.Adapter构造方法的理解
使用Adapter需要实现一下的函数:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    return null;
}
 
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {}
 
@Override
public int getItemCount() {
    return 0;
}

其中onCreateViewHolder()负责为Item创建视图,onBindViewHolder()负责将数据绑定到Item的视图上。那么接下来就需要有ViewHolder了。
通过实现以上方法便可实现一个简易的RecycleView,但如果需要时间多个Item的View视图的则需要实现以下方法:

private static final int TYPE_TOPIC = 0;
private static final int TYPE_TITLE = 1;
 
Override
public int getItemViewType(int position) {}

通过getItemViewType()为每个item设置好它的类型后在即可在onCreateViewHolder()根据Type创建相应的视图。

更多可以参考:https://blog.csdn.net/fyq520521/article/details/79218618

你可能感兴趣的:(开发小知识随手记)