Android开发过程遇到的问题积累

在安卓开发过程中,难免会遇到一系列蛋疼的问题,解决姿势基本都是谷歌、百度,但是时间久了还是会忘记,所以有必要做一下总结,下次遇到可以方便快速的查看并解决。

Gradle配置

http://wuxiaolong.me/categories/Gradle/

AndroidStudio统一版本问题

在开发的过程中,难免会在项目中依赖一些第三方的或者自己封装的Librariy,此时不同的lib中builde.gradle中依赖的库版本可能不一样,所以我们要统一整个项目中所依赖的库版本

解决办法如下:

1、在整个项目中新建config.gradle:
ext{
    android=[
            compileSdkVersion       : 26,
            minSdkVersion           : 21,
            targetSdkVersion        : 26,
            versionCode             : 1,
            versionName             : "1.0",
            androidSupportVersion   : "26.0.1",
            retrofitVersion         : "2.3.0",
            rxJavaVersion           : "2.1.0",
            rxAndroidVersio         : "2.0.1",
            okhttpVersion           : "3.6.0",
            constraintlayou         : "1.1.0-beta3",
            gsonVersion             : "2.8.0",
            glideVersion           : "3.7.0",
    ]
    dependencies=[
        "appcompat-v7"    : "com.android.support:appcompat-v7:${android["androidSupportVersion"]}",
        "constraint-layout"   :"com.android.support.constraint:constraint-layout:${android["constraintlayout"]}",
        "design"    :"com.android.support:design:${android["androidSupportVersion"]}",
        "retrofit"    :"com.squareup.retrofit2:retrofit:${android["retrofitVersion"]}",
        "retrofit-adapter-rxjava"    :"com.squareup.retrofit2:adapter-rxjava2:${android["retrofitVersion"]}",
        "retrofit-converter-gson"    :"com.squareup.retrofit2:converter-gson:${android["retrofitVersion"]}",
        "okhttp"    :"com.squareup.okhttp3:okhttp:${android["okhttpVersion"]}",
        "okhttp-logging-interceptor"    :"com.squareup.okhttp3:logging-interceptor:${android["okhttpVersion"]}",
        "rxjava"    :"io.reactivex.rxjava2:rxjava:${android["rxJavaVersion"]}",
        "rxandroid"    :"io.reactivex.rxjava2:rxandroid:${android["rxAndroidVersion"]}",
        "gson"    :"com.google.code.gson:gson:${android["gsonVersion"]}",
        "glide"    :"com.github.bumptech.glide:glide:${android["glideVersion"]}",  

    ]
}                      
2、在整个项目中新建builde.gradle中添加:
apply from : "config.gradle"
3、在app或者lib的builde.gradle中添加:
minSdkVersion rootProject.ext.android["minSdkVersion"]
targetSdkVersion rootProject.ext.android["targetSdkVersion"]
versionCode rootProject.ext.android["versionCode"]
versionName rootProject.ext.android["versionName"]

dependencies {
    compile rootProject.ext.dependencies["appcompat-v7
    compile rootProject.ext.dependencies["constraint-layout"]
    compile rootProject.ext.dependencies["design"]
    compile rootProject.ext.dependencies["rxjava"]
    compile rootProject.ext.dependencies["rxandroid"]
    compile rootProject.ext.dependencies["gson"]
    compile rootProject.ext.dependencies["glide"]
}

项目模块资源目录划分

在moudle下的builde.gradle的android下新建:

sourceSets {
        main {
            res.srcDirs =
                    [
                            'src/main/res',
                            'src/main/res-xxx1',//首页
                            'src/main/res-xxx2',//我的
                            'src/main/res-xxx3'//购物车
                    ]
        }
    }

然后在src/main下创建对应的目录

AndroidStudio连不上手机

命令行执行(XXXX是执行第一行之后显示的第一个端口号):
netstat -aon|findstr 5037
taskkill /pid XXXX /f

沉浸式状态栏

https://github.com/laobie/StatusBarUtil
https://github.com/gyf-dev/ImmersionBar

<style name="TranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowTranslucentStatus">false</item>
    <item name="android:windowTranslucentNavigation">false</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

禁止滑动布局如ScorllView、RecyclerView滑到顶部的波浪背影效果

    android:scrollbars="none"
    android:fadingEdge="none"
    android:overScrollMode="never" 

Activity的状态保存

在 Activity 生命周期中,Android 会在销毁 Activity 之前调用 onSaveInstanceState(),以便您保存有关应用状态的数据。 然后,您可以在 onCreate() 或 onRestoreInstanceState() 期间恢复 Activity 状态。

Activity之间的传值

1、传递List
ArrayList<String> info = new ArrayList<String>();  

info.add(name);  

info.add(website);  

info.add(weibo);  

Intent intent = new Intent(MainActivity.this, ResultActivity.class);  

intent.putStringArrayListExtra("StringList", info);  

startActivity(intent); 
取出List
ArrayList<String> infoList = new ArrayList<String>();  

infoList = getIntent().getStringArrayListExtra("StringList"); 
2、传递Object

1 使用Serializable方式
前提:Object需要实现Serializable接口
用Serializable方式传递Object的语法:bundle.putSerializable(key,object);
用Serializable方式接收Object的语法:object=(Object) getIntent().getSerializableExtra(key);
实现Serializable接口就是把对象序列化,然后再传输,和Java的常用编程没什么明显区别,而且Object不需要明显改变,推荐用这种方式。

3、传递存储的Object的List
    ArrayList<SerInfo> listObj = new ArrayList<SerInfo>();  

    SerInfo serInfo1 = new SerInfo(name, website, weibo);  

    SerInfo serInfo2 = new SerInfo(name, website, weibo);  

    listObj.add(serInfo1);  

    listObj.add(serInfo2);  

    Intent intent = new Intent();  

    intent.setClass(MainActivity.this, ResultActivity.class);  

    intent.putExtra("listobj", (Serializable) listObj);  

    startActivity(intent);  

取出

ArrayList<SerInfo> listObj =  (ArrayList<SerInfo>) getIntent().getSerializableExtra("listobj");  

切换Fragment

private void initFragment() {
        mOnLineGoodsFragment();
        mOffLineGoodsFragment = new  OffLineGoodsFragment();
        //添加到数组
        mFragments = new Fragment[]{mOnLineGoodsFragment, mOffLineGoodsFragment};
        //开启事务
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction ft = fragmentManager.beginTransaction();
        //添加首页
        ft.add(R.id.frame_content, mFragments[0]).commit();
        //默认设置为第0个
        setIndexSelected(0);
    }

private void setIndexSelected(int index) {
      if (mIndex == index) {
            return;
     }
      FragmentManager fragmentManager = getSupportFragmentManager();
      FragmentTransaction ft = fragmentManager.beginTransaction();
      //隐藏
      ft.hide(mFragments[mIndex]);
      //判断是否添加
      if (!mFragments[index].isAdded(){
            ft.add(R.id.frame_content, mFragments[index]).show(mFragments[index]);
        } else {
            ft.show(mFragments[index]);
    }
        ft.commit();
        //再次赋值
        mIndex = index;
    }

TextView

https://www.2cto.com/kf/201708/668884.html

让TextView部分文字显示其他颜色出了使用SpannableString 外还可以使用:

<string name="hth_signed_people">
        <Data><![CDATA[<font color="#fd5729">%1$s/</font>%2$s人已报名]]></Data>
    </string>
tv.setText(Html.fromHtml(String.format(getResources().getString(R.string.xxxxxxx),"222","33333" ));

EditText

自定义光标并且去除下划线
android:textCursorDrawable="@drawable/edit_cuser_color"
android:background="@null"

“edit_cuser_color”:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <size android:width="2dp" />
    <solid android:color="@color/green_71C74C"  />
</shape>
禁止换行
    android:maxLines="1"
    android:singLine="true"
EditText设置可以编辑和不可编辑状态

EditText searchView = (EditText) findViewById(R.id.search_text);
searchView.setOnFocusChangeListener(new android.view.View.
OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
// 此处为得到焦点时的处理内容
} else {
// 此处为失去焦点时的处理内容
}
}
});

searchView.setFocusable(true);
searchView.setFocusableInTouchMode(true);
searchView.requestFocus();

searchView.clearFocus();//失去焦点
searchView.requestFocus();//获取焦点

ImageView

http://blog.csdn.net/zhuwentao2150/article/details/52171794

AndroidStudio常用快捷键

1.全局搜索文件:双击Shift
2.Ctrl+Q:把光标移至方法处,按此组合键可快速查看方法的说明文档
3.Ctrl + + 展开代码
4.Ctrl + - 折叠代码
5.Ctrl+Alt+ left/right 返回至上次浏览的位置
http://blog.csdn.net/Me_Dong/article/details/53037201

clipToPadding解决listview滚动问题

clipToPadding:
就是说控件的绘制区域是否在padding里面的,true的情况下如果你设置了padding那么绘制的区域就往里 缩,假设 内部有个属性设置了PaddingTop但是滑动的时候就忽视paddingTop的 则使用该属性如设置android:clipToPadding=false

clipChildren:
还有个类似的clipChildren,这个的作用是,如果子view比parent大的时候,是否裁剪,默认为true裁剪。也是在绘制阶段作用的。
举个例子,在100*100的布局里放个200*200的button会怎么样?
默认情况下,Button被裁剪,只有parent内部的可以显示,clipChildren设置为true之后,如右图所示,整个button都显示出来了,非常简单.注意android:clipChildren=”false”必须在最外层布局里写才有效果。这个属性在做动画的时候非常有用,因为默认是被裁剪的,所以一个view无法超过parent,在放大或者移动的动画中就可能被裁剪,用了此属性就不会被裁剪了。

1、clipToPadding 是否可以在padding区域内绘制
2、子view是否可以超出父view的区域

自定义View的问题

自定义属性的两种方法

https://github.com/linsir6/AndroidNote/blob/master/AndroidNote/Android%E8%87%AA%E5%AE%9A%E4%B9%89View/%E8%87%AA%E5%AE%9A%E4%B9%89View%E5%85%A5%E9%97%A8.md

RxTools

http://blog.csdn.net/m0_37314675/article/details/77850849

懒加载

public abstract class BaseLazyFragment extends Fragment {

    protected Activity mActivity;
    protected View mRootView;

    /**
     * 是否对用户可见
     */
    protected boolean mIsVisible;
    /**
     * 是否加载完成
     * 当执行完onViewCreated方法后即为true
     */
    protected boolean mIsPrepare;

    /**
     * 是否加载完成
     * 当执行完onViewCreated方法后即为true
     */
    protected boolean mIsImmersion;

    protected ImmersionBar mImmersionBar;
    private Unbinder unbinder;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mActivity = (Activity) context;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mRootView = inflater.inflate(setLayoutId(), container, false);
        return mRootView;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        unbinder = ButterKnife.bind(this, mRootView);
        if (isLazyLoad()) {
            mIsPrepare = true;
            mIsImmersion = true;
            onLazyLoad();
        } else {
            initData();
            if (isImmersionBarEnabled())
                initImmersionBar();
        }
        initView();
        setListener();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unbinder.unbind();
        if (mImmersionBar != null)
            mImmersionBar.destroy();
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (getUserVisibleHint()) {
            mIsVisible = true;
            onVisible();
        } else {
            mIsVisible = false;
            onInvisible();
        }
    }

    /**
     * 是否懒加载
     *
     * @return the boolean
     */
    protected boolean isLazyLoad() {
        return true;
    }

    /**
     * 是否在Fragment使用沉浸式
     *
     * @return the boolean
     */
    protected boolean isImmersionBarEnabled() {
        return true;
    }

    /**
     * 用户可见时执行的操作
     */
    protected void onVisible() {
        onLazyLoad();
    }

    private void onLazyLoad() {
        if (mIsVisible && mIsPrepare) {
            mIsPrepare = false;
            initData();
        }
        if (mIsVisible && mIsImmersion && isImmersionBarEnabled()) {
            initImmersionBar();
        }
    }

    /**
     * Sets layout id.
     *
     * @return the layout id
     */
    protected abstract int setLayoutId();

    /**
     * 初始化数据
     */
    protected void initData() {

    }

    /**
     * 初始化沉浸式
     */
    protected void initImmersionBar() {
        mImmersionBar = ImmersionBar.with(this);
        mImmersionBar.keyboardEnable(true).navigationBarWithKitkatEnable(false).init();
    }

    /**
     * view与数据绑定
     */
    protected void initView() {

    }

    /**
     * 设置监听
     */
    protected void setListener() {

    }

    /**
     * 用户不可见执行
     */
    protected void onInvisible() {

    }

    /**
     * 找到activity的控件
     *
     * @param <T> the type parameter
     * @param id  the id
     * @return the t
     */
    @SuppressWarnings("unchecked")
    protected <T extends View> T findActivityViewById(@IdRes int id) {
        return (T) mActivity.findViewById(id);
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值