懒惰的自己,自带标题栏的BaseActivity

自己的新app项目,做了一个BaseActivity,参考了不少的资料,根据自己的需要改了不少.感觉为了偷懒已经到极限了

package com.corncq.mybaseframe;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import com.corncq.activity.ComplaintActivity;
import com.corncq.dxcx_user.R;
import com.corncq.my_enum.LayoutSelect;
import com.corncq.my_enum.PopWindowEnum;
import com.corncq.util.MyTextWatcher;
import com.corncq.util.SelectPicPopupWindow;
import com.corncq.util.SysApplication;
import com.corncq.util.UIHandler;
import com.corncq.view.CustomScrollView;
import com.corncq.view.XListView;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by xiione on 2016/9/20.
 * activity基类
 */
public abstract class BaseActivity extends FragmentActivity implements View.OnClickListener {

    private CustomScrollView customScrollView;
    private ScrollView scrollView;
    private LinearLayout linearLayout;

    protected MyDialog progress; //加载进度圈
    private Intent intent;
    protected DisplayMetrics dm; //屏幕测量工具

    protected MyTextWatcher watcher; //监测输入(如输入框,文本框等),后面贴代码

    public boolean isWatcher = false; //是否开启控件监听,需要自己设置
    public boolean isOtherWatcher = false; //是否开启控件监听,需要自己设置
    public SelectPicPopupWindow basePopWindow; //弹出的pop

    public BaseActivity() {

    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //添加到回收站,方便一次性关闭所有打开过的页面
        SysApplication.getInstance().addActivity(this);
        dm = getResources().getDisplayMetrics();
        setContentView(R.layout.activity_main);
        progress = MyDialog.getInstance(this);
        Bundle bundle = getIntent().getExtras();
        initParms(bundle);
        customScrollView = (CustomScrollView) findViewById(R.id.customScrollView);
        scrollView = (ScrollView) findViewById(R.id.scrollView);
        linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
        if (getScreen_exchange()) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        //添加视图
        View mView = bindView();
        //判断视图是否为空
        if (null == mView) {
            //判断布局是否为空
            if (bindLayout() != 0) {
                //如果不为空,根据布局id,获取视图
                mView = LayoutInflater.from(this).inflate(bindLayout(), null, false);
            }
        }
        //获取到视图
        if (null != mView) {
            //选择 页面类型,是否可以滑动)
            switch (selectView()) {
                case CUSTOMSCROLLVIEW: //自定义scrollview,内部listview可滑动
                    customScrollView.setVisibility(View.VISIBLE);
                    customScrollView.addView(mView);
                    break;
                case SCROLLVIEW: //系统scrollview,内部listview不可滑动,必须完全显示
                    scrollView.setVisibility(View.VISIBLE);
                    scrollView.addView(mView);
                    break;
                case LINEARLAYOUT: //linearlayout
                    linearLayout.setVisibility(View.VISIBLE);
                    linearLayout.addView(mView);
                    mView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));

                    break;
            }
        }
        watcher = new MyTextWatcher();
        setHandler();
        initView();
        initData();
    }

    /**
     * 选择横竖屏显示,重写此方法可以更改,这里默认为竖屏
     *
     * @return true 为横屏, false 为竖屏
     */
    public boolean getScreen_exchange() {
        return false;
    }


    /**
     * [选择页面类型是否可滑动]
     *
     * @return
     */
    public abstract LayoutSelect selectView();

    /**
     * [绑定视图]
     *
     * @return
     */
    public abstract View bindView();

    /**
     * [绑定布局]
     *
     * @return
     */
    public abstract int bindLayout();

    /**
     * 获取标题栏实例 ,当不需要title栏的时候可以隐藏
     *
     * @return
     */
    public RelativeLayout getTitleLayout() {
        return (RelativeLayout) findViewById(R.id.title_layout);
    }

    /**
     * 设置左侧图片显示内容并设定点击事件
     *
     * @return
     */
    public void setTitleLeftImg(int resID) {
        ImageView imageView = (ImageView) findViewById(R.id.title_img_left);
        imageView.setVisibility(View.VISIBLE);
        imageView.setOnClickListener(this);
        imageView.setImageResource(resID);
    }

    /**
     * 设置右上角文本名称
     *
     * @param text 需要显示的文本
     */
    public void setRightText(String text) {
        TextView textView = (TextView) findViewById(R.id.title_text_right);
        textView.setVisibility(View.VISIBLE);
        textView.setText(text);
        textView.setOnClickListener(this);
    }

    /**
     * 设置右上角文本名称,并带有图片
     *
     * @param text       需要显示的文本
     * @param leftImage  文本左侧图片,没有为null
     * @param rightImage 文本右侧图片,没有为null
     */
    public void setRightTextImage(String text, int leftImage, int rightImage) {
        TextView textView = (TextView) findViewById(R.id.title_text_right);
        textView.setOnClickListener(this);
        textView.setVisibility(View.VISIBLE);
        textView.setText(text);
        Drawable left = null;
        Drawable right = null;
        try {
            if (leftImage != 0 && rightImage != 0) {
                left = getResources().getDrawable(leftImage);
                right = getResources().getDrawable(rightImage);
                //必须设置图片大小,否则不显示【0,0表示坐标x,y坐标,50,50表示宽高】
                //四个参数分别表示文本左、上、右、下四个方向上的图片,null表示没有图片
                left.setBounds(0, 0, 30, 30);
                right.setBounds(0, 0, 30, 30);
            } else if (leftImage != 0) {
                left = getResources().getDrawable(leftImage);
                left.setBounds(0, 0, 30, 30);
            } else if (rightImage != 0) {
                right = getResources().getDrawable(rightImage);
                right.setBounds(0, 0, 30, 30);
            }
            textView.setCompoundDrawables(left, null, right, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置标题栏名称
     *
     * @param text 需要显示的标题名
     */
    public void setTitleName(String text) {
        TextView textView = (TextView) findViewById(R.id.title_name);
        textView.setText(text);
    }

    /**
     * 设置右侧图片显示内容并设定点击事件
     *
     * @return
     */
    public void setTitleRightImg(int resID) {
        ImageView imageView = (ImageView) findViewById(R.id.title_img_right);
        imageView.setVisibility(View.VISIBLE);
        imageView.setOnClickListener(this);
        imageView.setImageResource(resID);
    }


    /**
     * 添加初始化布局,必须实现
     */
    protected abstract void initView();

    /**
     * 添加初始化数据,必须实现
     */
    public abstract void initData();

    /**
     * [初始化参数]
     *
     * @param parms
     */
    public abstract void initParms(Bundle parms);

    /**
     * [简化Toast]
     *
     * @param msg
     */
    protected void showToast(String msg) {
        Toast.makeText(BaseActivity.this, msg, Toast.LENGTH_SHORT).show();
    }

    /**
     * [页面跳转]
     *
     * @param clz
     */
    public void startActivity(Class<?> clz) {
        intent = new Intent(BaseActivity.this, clz);
        startActivity(intent);
    }

    /**
     * [携带数据的页面跳转]
     *
     * @param clz
     * @param bundle
     */
    public void startActivity(Class<?> clz, Bundle bundle) {
        intent = new Intent();
        intent.setClass(this, clz);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

    /**
     * [含有Bundle通过Class打开编辑界面,有返回事件的跳转]
     *
     * @param cls
     * @param bundle
     * @param requestCode
     */
    public void startActivityForResult(Class<?> cls, Bundle bundle, int requestCode) {
        intent = new Intent();
        intent.setClass(this, cls);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivityForResult(intent, requestCode);
    }

<span style="white-space:pre">	</span>/**
<span style="white-space:pre">	</span>*自定一定handler,后面贴代码
<span style="white-space:pre">	</span>*/
    protected UIHandler handler = new UIHandler(Looper.getMainLooper());

    private void setHandler() {
        handler.setHandler(new UIHandler.UIHandlerListener() {
            public void UISendMessage(Message msg) {
                baseHandle(msg);
            }
        });
    }

    protected abstract void baseHandle(Message msg);

    /**
     * 通过资源id获取string
     *
     * @param resId
     * @return
     */
    public String getBaseString(int resId) {
        return getResources().getString(resId);
    }

    /**
     * 通过资源id获取color
     *
     * @param resId
     * @return
     */
    public int getBaseColor(int resId) {
        return getResources().getColor(resId);
    }

    /**
     * 通过资源id获取drawable
     *
     * @param resId
     * @return
     */
    public Drawable getBaseDrawable(int resId) {
        return getResources().getDrawable(resId);
    }

    /**
     * 当使用了自定义上拉加载,下拉刷新 的XListView时,加载或刷新完成时调用
     *
     * @param xListView
     */
    public void stopLoad(XListView xListView) {
        xListView.stopRefresh();
        xListView.stopLoadMore();
        xListView.setRefreshTime("刚刚");
    }

    /**
     * 选择器
     *
     * @param list   显示的列表内容
     * @param kefu   客服电话
     * @param bundle 携带信息
     */
    public void creatPop(List<String> list, String kefu, final Bundle bundle) {
        final ImageView mView = (ImageView) findViewById(R.id.title_img_right);
        basePopWindow = new SelectPicPopupWindow(PopWindowEnum.KEFU_COMPLAINT, this, list, new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int postion, long l) {
                TextView text = (TextView) view;
                String str = text.getText().toString();
                if (str.equals("客服")) {//客服
                    Intent intent = new Intent(Intent.ACTION_CALL);
                    Uri data = Uri.parse("tel:" + "10086");
                    intent.setData(data);
                    startActivity(intent);
                } else if (str.equals("投诉")) {//投诉
                    startActivity(ComplaintActivity.class, bundle);
                }
                basePopWindow.dismiss();
            }
        }, mView.getWidth());
        basePopWindow.showAsDropDown(mView, -10, -10);
    }

    @Override
    protected void onResume() {
        super.onResume();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message msg;
                if (watcher != null) {
                    Log.e("onResume", "开始监听");
                    while (isWatcher) {
                        try {
                            if (watcher.getHasEmpty() || isOtherWatcher) { //只有全部为false才是数据填写完毕
                                msg = handler.obtainMessage();
                                msg.what = 10001;
                                handler.sendMessage(msg);
                            } else {
                                msg = handler.obtainMessage();
                                msg.what = 10002;
                                handler.sendMessage(msg);
                            }
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                } else {
                    Log.e("onResume", "监听失败");
                }
            }
        }).start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        isWatcher = false;
    }

    /**
     * 点击按钮,使用textview,有三个状态,不可点击,未点击,点击
     * @param msgWhat
     * @param view
     */
    protected void textViewWatcher(int msgWhat, TextView view) {
        switch (msgWhat) {
            case 10001: //有空数据
                view.setClickable(false);
                view.setSelected(true);
                break;
            case 10002: //填写完毕
                view.setClickable(true);
                view.setSelected(false);
                break;
        }
    }
}
布局文件 activity_main

基本所有的页面都有一个标题栏.所以,标题栏都直接写在页面上了.当然.这样会多用2层布局,不建议这样做,我就是太懒了

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:id="@+id/activity_main"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:focusable="true"
              android:background="@color/white"
              android:focusableInTouchMode="true"
              tools:context="com.corncq.dxcx_user.MainActivity">

    <include layout="@layout/title_layout"></include>

    <LinearLayout android:id="@+id/linearLayout"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:visibility="gone"
                  android:background="@color/white"
                  android:orientation="vertical">

    </LinearLayout>


    <com.corncq.view.CustomScrollView android:id="@+id/customScrollView"
                                      android:visibility="gone"
                                      android:layout_width="match_parent"
                                      android:layout_height="wrap_content"
                                      android:background="@color/white"
                                      android:scrollbars="none"
    >

    </com.corncq.view.CustomScrollView>

    <ScrollView android:id="@+id/scrollView"
                android:visibility="gone"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/white"
                android:scrollbars="none">

    </ScrollView>
</LinearLayout>

这里出现了一个自定义的CustomScrollView,作用是内部的listview也可以上下滑动,而外部的也可以滑动,有需要的可以自己去百度

自定的UIHandler,直接把数据请求写进去了,可以使用反射确定是否获取到所需要的必要数据,

/**
 * Created by xiione on 2016/9/21.
 * handler工具
 */
public class UIHandler<T> extends Handler {

    private UIHandlerListener listener;
    private StringBuffer buffer;

    public UIHandler(Looper looper) {
        super(looper);
        buffer = new StringBuffer();
    }

    public UIHandler(Looper looper, UIHandlerListener listener) {
        super(looper);
        this.listener = listener;
        buffer = new StringBuffer();
    }

    public void setHandler(UIHandlerListener listener) {
        this.listener = listener;
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (listener != null) {
            listener.UISendMessage(msg);
        }
    }

    /**
     * @param httpUrl 路径
     * @param params  接口需要的数据
     * @param context 上下文
     * @param tClass  反射类
     * @param mList   不能为空的字段名集合
     * @param msgWhat msg.what,确定返回值
     * @return
     */
    public void handleHttpRequest(String httpUrl, String params, Context context, Class<T> tClass, List<String> mList, int msgWhat) {
        Message msg = this.obtainMessage();
        try {
            String data = HttpConnection.request(httpUrl, params, context);
            Object object = new Gson().fromJson(data, tClass);
            if (!myIterator(object, mList)) {
                msg.what = 400;
                this.handleMessage(msg);
                return;
            } else {
                msg.what = msgWhat;
                msg.obj = object;
                this.handleMessage(msg);
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
            msg.what = 400;
            this.handleMessage(msg);
        }
    }

    /**
     *本地测试,不需要服务器,自己使用代码进行测试
     * @param data    json 字符串
     * @param tClass  反射的类
     * @param mList   不为空的字段名
     * @param msgWhat msg.what,
     */
    public void myTest(String data, Class<T> tClass, List<String> mList, int msgWhat) {
        Message msg = this.obtainMessage();
        try {
            Log.e("myTest", "开始------");
            Object object = new Gson().fromJson(data, tClass);
            //当有不能为空的字段为空时,msg.what = 400;
            if (!myIterator(object, mList)) {
                Log.e("错误", "错误=======");
                msg.what = 400;
                this.handleMessage(msg);
            } else {
                Log.e("解析成功", "-----------");
                msg.what = msgWhat;
                msg.obj = object;
                this.handleMessage(msg);
            }
            Log.e("myTest", "开始------");
        } catch (Exception e) {
            e.printStackTrace();
            msg.what = 400;
            this.handleMessage(msg);
        }
    }

    /**
     * 迭代器,用反射找到一个类中所有的内部类
     *
     * @param object 需要反射的类的对象实例
     * @param mList  不能为空的字段名
     */
    private boolean myIterator(Object object, List<String> mList) throws NoSuchMethodException, IllegalAccessException, InstantiationException {
        Class mClass = object.getClass();
        Log.e("看看这个类名", "就是这个==" + mClass.getName());
        Field[] fd = mClass.getDeclaredFields();
        for (Field field : fd) {
            //获取属性名称
            String name = field.getName();
            //打破封装
            field.setAccessible(true);
            Object obj = field.get(object);
            //判断该属性是否为空
            if (null == obj || "".equals(obj.toString())) {
                buffer.append(name + ", ");
                //如果为空,与传入的不能为空的字段比较
                for (String str : mList) {
                    //如果相同,则返回false,表示数据加载错误
                    if (str.equals(name)) {
                        return false;
                    }
                }
            }
            //判断属性是否包含 data字段(自己把所有的内部类都命名带有Data,由于驼峰命名,有不想写太多判断,使用"ata"),如果有,则该属性为对象,需要继续判断
            if (name.contains("ata")) {
                if (!myIterator(obj, mList)) {
                    return false;
                }
            }
        }
        return true;
    }

    public String getNullName() {
        return buffer.toString();
    }

    public interface UIHandlerListener {

        void UISendMessage(Message msg);

    }



产品经理要求有输入或者选择器的页面如果有提交功能的按钮,则需所有的数据填写清楚才能点击,所以写了一个监听功能的工具,感觉还不错

/**
 * Created by xiione on 2016/9/29.
 * 文本框与输入框输入监听,电话号码格式判断,
 */
public class MyTextWatcher implements TextWatcher {

    private List<TextView> mList; //需要判空的textview与editText的集合
    private boolean hasEmpty = true; //判断是否有空值

    public List<TextView> getmList() {
        return mList;
    }

    public MyTextWatcher() {
        mList = new ArrayList<>();
    }

    public boolean isEmpty() {
        for (int i = 0; i < mList.size(); i++) {
            if (mList.get(i).getText().toString().isEmpty()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 添加textview与edittext,并添加事件
     * @param textView
     */
    public void addTextView(TextView textView) {
        mList.add(textView);
        textView.addTextChangedListener(this);
    }

    public void deleteTextView(TextView textView){
        mList.remove(textView);
    }


    /**
     * 获取空值状态
     *
     * @return
     */
    public boolean getHasEmpty() {
        return hasEmpty;
    }

    /**
     * edittext使用,用于,edittext获取焦点时,提示文字消失
     *
     * @param mInfo
     */
    public static void setEditText(EditText mInfo) {
        mInfo.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            public void onFocusChange(View v, boolean hasFocus) {
                Log.e("获取焦点", "输入框获取焦点");
                EditText _v = (EditText) v;
                if (!hasFocus) {// 失去焦点
                    _v.setHint(_v.getTag().toString());
                } else {
                    String hint = _v.getHint().toString();
                    _v.setTag(hint);
                    _v.setHint("");
                }
            }
        });
    }

    /**
     * 电话号码监听
     *
     * @param context
     * @param mInfo
     */
    public static void setPhoneEdit(final Context context, final EditText mInfo) {
        mInfo.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean b) {
                Log.e("电话号码获取焦点", "电话号码输入框获取焦点");
                EditText _v = (EditText) view;
                if (!b) {// 失去焦点
                    _v.setHint(_v.getTag().toString());
                    if (!isMobileNO(mInfo.getText().toString())) {
                        Toast.makeText(context, "电话号码格式错误", Toast.LENGTH_SHORT).show();
                        mInfo.setText("");
                    }
                } else {
                    String hint = _v.getHint().toString();
                    _v.setTag(hint);
                    _v.setHint("");
                }
            }
        });
    }

    /**
     * 验证码监听
     *
     * @param context
     * @param mInfo
     */
    public static void setCodeEdit(final Context context, final EditText mInfo) {
        mInfo.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean b) {
                Log.e("验证码获取焦点", "验证码输入框获取焦点");
                EditText _v = (EditText) view;
                if (!b) {// 失去焦点
                    _v.setHint(_v.getTag().toString());
                    if (mInfo.getText().toString().length() != 6) {
                        Toast.makeText(context, "请输入6位验证码", Toast.LENGTH_SHORT).show();
                        mInfo.setText("");
                    }
                } else {
                    String hint = _v.getHint().toString();
                    _v.setTag(hint);
                    _v.setHint("");
                }
            }
        });

    }

    /**
     *验证手机格式
     */
    public static boolean isMobileNO(String mobiles) {
    /*
    移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188
    联通:130、131、132、152、155、156、185、186
    电信:133、153、180、189、(1349卫通)
    总结起来就是第一位必定为1,第二位必定为3或5或8,其他位置的可以为0-9
    */
        String telRegex = "[1][358]\\d{9}";//"[1]"代表第1位为数字1,"[358]"代表第二位可以为3、5、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有9位。
        if (TextUtils.isEmpty(mobiles)) return false;
        else return mobiles.matches(telRegex);
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        hasEmpty = isEmpty();
    }
}

好了,基本就这样了,代码简单也不用解释了,直接就能看懂,现在感觉还行,不知道以后自己看会是个什么样子的,哎,有点期待






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值