您的位置:首页 > 移动开发 > Android开发

android小技巧

2017-06-29 14:40 260 查看
1. 布局技巧

父布局居中

android:layout_centerInParent="true"
android:layout_gravity="center"


多余字不显示

android:singleLine="true"


字体太大时避免显示不全

android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"


子控件可以设置为全局固定。可用于实现布局滚动,折叠效果且要求固定Toolbar时

app:layout_collapseMode="pin"


toolbar偏移量为0

app:contentInsetStart="0dp"


横竖屏切换及editTextview键盘出现时视图不再上移

<activity
android:name=".LoadingActivity"
android:configChanges="orientation|keyboardHidden"
android:windowSoftInputMode="adjustPan|stateHidden"
>


2. 可复用toolbar

nav_toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/grayc"
android:theme="@style/AppTheme.AppBarOverlay"
>

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginTop="20dp"
android:background="@color/white"

app:popupTheme="@style/AppTheme.PopupOverlay">

<!--<ImageView-->
<!--android:id="@+id/im_about_back"-->
<!--android:layout_width="40dp"-->
<!--android:layout_height="40dp"-->
<!--android:layout_gravity="left"-->
<!--android:padding="10dp"-->
<!--android:src="@mipmap/ic_back_green" />-->

<TextView
android:id="@+id/toolbar_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:layout_centerInParent="true"
android:layout_gravity="center"
app:layout_collapseMode="pin"
app:contentInsetStart="0dp"
android:textSize="17sp" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>


layout中引用

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


java调用

initToolbar();

private void initToolbar() {
//        initToolbar();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
TextView tv=(TextView)findViewById(R.id.toolbar_tv);
toolbar.setTitle("");
tv.setText("关于我们");
toolbar.setNavigationIcon(R.mipmap.ic_back_green);//后退按钮
setSupportActionBar(toolbar);

//后退监听
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
//                Toast.makeText(AboutActivity.this,"后退", Toast.LENGTH_SHORT).show();
}
});
}


3.沉浸式状态栏

//浸入式状态栏
@TargetApi(19)
private void initWindow() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}


4.通用BaseActivity

package com.sjs.dz.rzxt3;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Window;
import android.widget.TextView;
import android.widget.Toast;

import com.sjs.dz.rzxt3.R;
import com.sjs.dz.rzxt3.base.SysApplication;

/**
* Created by 李江涛 on 2017/6/29.
* 说明:
*/

public abstract class BaseActivity extends AppCompatActivity implements View.OnClickListener{
private long lastClick = 0;
public Toolbar toolbar;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
SysApplication.getInstance().addActivity(this);
setContentView(getLayoutId());
initView();
loadData();
setListener();
}

@Override
public void onClick(View v) {
if (fastClick())
widgetClick(v);
}

@Override
public void finish() {
SysApplication.getInstance().removeActivity(this);
super.finish();
}

/**
* 设置ContentView
* @return R.layout.xxx
*/
protected abstract int getLayoutId();

/**
* 初始化View
*/
protected abstract void initView();
/**
* add Listener
*/
protected abstract void setListener();

/**
* 下载数据
*/
protected abstract void loadData();
/**
* 将数据更新到View
*/
protected abstract void initDateToView();
/**
* view点击
* @param v
*/
public abstract void widgetClick(View v);

/**
* 防止快速点击
* @return
*/
private boolean fastClick() {
if (System.currentTimeMillis() - lastClick <= 1000) {
return false;
}
lastClick = System.currentTimeMillis();
return true;
}

/**
* 通用ToolBar 当存在是调用 布局文件 必须包含 single_toolbar.xml
* @param title 标题内容
* @param isBack 是否存在反回功能
*/
protected void setToolBar(String title,boolean isBack) {
toolbar = $findViewById(R.id.toolbar);
toolbar.setVisibility(View.VISIBLE);
TextView tv_title = $findViewById(R.id.tv_title);
tv_title.setText(title);
toolbar.setTitle("");
setSupportActionBar(toolbar);
if (isBack) {
toolbar.setNavigationIcon(R.mipmap.ic_back_green);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}

/**
* findViewById
* @param resId
* @param <T>
* @return
*/
public <T extends View> T $findViewById(int resId) {
return (T) findViewById(resId);
}

/**
*  Toast
* @param msg 消息
*/
protected void $toast(CharSequence msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}

/**
* startActivity
* @param cls 需要启动的Activity
*/
protected void $startActivity(Class<?> cls) {
$startActivity(cls, null);
}

/**
* startActivity 存在Bundle
* @param cls 需要启动的Activity
* @param bundle Bundle数据
*/
protected void $startActivity(Class<?> cls, Bundle bundle) {
Intent intent = new Intent(this, cls);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivity(intent);
}

/**
* startActivityForResult
* @param cls 需要启动的Activity
* @param requestCode 请求码
*/
protected void $startActivityForResult(Class<?> cls, int requestCode) {
$startActivityForResult(cls, null, requestCode);
}

/**
* startActivityForResult 存在Bundle
* @param cls 需要启动的Activity
* @param bundle Bundle数据
* @param requestCode 请求码
*/
protected void $startActivityForResult(Class<?> cls, Bundle bundle, int requestCode) {
Intent intent = new Intent(this, cls);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivityForResult(intent, requestCode);
}

/**
* 获取 传入 Bundle
* @return
*/
protected Bundle $getIntentExtra() {
Intent intent = getIntent();
Bundle bundle = null;
if (null != intent)
bundle = intent.getExtras();
return bundle;
}

}


ParentActivity

package com.sjs.dz.rzxt3;

import android.view.View;

/**
* Created by 李江涛 on 2017/6/29.
* 说明:
*/

public class ParentActivity extends BaseActivity {
@Override
protected int getLayoutId() {
return 0;
}

@Override
protected void initView() {

}

@Override
protected void setListener() {

}

@Override
protected void loadData() {

}

@Override
protected void initDateToView() {

}

@Override
public void widgetClick(View v) {

}
}


MainActivity

package com.sjs.dz.rzxt3;

import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.MenuItem;
import android.view.View;

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

import com.sjs.dz.rzxt3.R;
import com.sjs.dz.rzxt3.ParentActivity;
import com.sjs.dz.rzxt3.BaseFragment;
import com.sjs.dz.rzxt3.listener.BottomNavigationChangeListener;

public class MainActivity extends ParentActivity {
private ViewPager viewPager;
private MenuItem menuItem;
private BottomNavigationView bottomNavigationView;
private NavigationView navgaView;

@Override
protected int getLayoutId() {
return R.layout.activity_main;
}

@Override
protected void initView() {
viewPager = $findViewById(R.id.viewpager);
bottomNavigationView = $findViewById(R.id.bottom_navigation);
navgaView = (NavigationView) findViewById(R.id.naviView_three);
}

@Override
protected void setListener() {
BottomNavigationChangeListener listener = new BottomNavigationChangeListener(this, bottomNavigationView, viewPager);
List<Fragment> list = new ArrayList<>();
for (int i=0;i<4;i++) {
Fragment fragment = BaseFragment.newInstance("di" + i);
list.add(fragment);
}
listener.setFragments(list);
navgaView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_me:
$startActivity(FirstActivity.class);
break;
}
return true;
}
});
}

@Override
protected void loadData() {

}

@Override
public void widgetClick(View v) {

}

}


SysApplication

package com.sjs.dz.rzxt3.base;

import android.app.Activity;
import android.app.Application;
import android.content.Context;

import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.nostra13.universalimageloader.utils.StorageUtils;

import java.io.File;
import java.util.ArrayList;

import com.sjs.dz.rzxt3.utils.CrashHandler;

public class SysApplication extends Application {
private static SysApplication instance;
public DisplayImageOptions options;
private ArrayList<Activity> activityList = new ArrayList<Activity>();

@Override
public void onCreate() {
super.onCreate();
instance = this;
CrashHandler crashHandler=new CrashHandler();
crashHandler.init(instance);
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
//SDKInitializer.initialize(instance);
setImageOptions();
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
//MultiDex.install(this);
}
public synchronized static SysApplication getInstance() {
return instance;
}

private void setImageOptions() {
File cacheDir = StorageUtils.getOwnCacheDirectory(this, "imageloader/Cache"); //缓存文件的存放地址
ImageLoaderConfiguration config = new ImageLoaderConfiguration
.Builder(this)
.memoryCacheExtraOptions(480, 800) // max width, max height
.threadPoolSize(3)//线程池内加载的数量
.threadPriority(Thread.NORM_PRIORITY - 2)  //降低线程的优先级保证主UI线程不受太大影响
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new WeakMemoryCache()) //建议内存设在5-10M,可以有比较好的表现  new WeakMemoryCache()
// .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //建议内存设在5-10M,可以有比较好的表现  new WeakMemoryCache()
//.memoryCacheSize(2 * 1024 * 1024)
.discCacheSize(50 * 1024 * 1024)
.discCacheFileNameGenerator(new Md5FileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO)
.discCacheFileCount(100) //缓存的文件数量
.diskCache(new UnlimitedDiskCache(cacheDir))
.defaultDisplayImageOptions(DisplayImageOptions.createSimple())
.imageDownloader(new BaseImageDownloader(this, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)
.writeDebugLogs() // Remove for release app
.build();
ImageLoader.getInstance().init(config);
}

public void addActivity(Activity activity) {
activityList.add(activity);
}
public void removeActivity(Activity activity) {
activityList.remove(activity);
}
/**
*     遍历所有Activity并finish
*/
public void exit() {
try {
for (Activity activity : activityList) {
activity.finish();
}
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*     杀进程
*/
@Override
public void onLowMemory() {
super.onLowMemory();
System.gc();
}
}


CrashHandler.java

package com.sjs.dz.rzxt3.utils;

/**
* Created by win on 2017/6/30.
*/

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

/**
* UncaughtException处理类,当程序发生Uncaught异常的时候,有该类来接管程序,并记录发送错误报告.
*
* Created by yuyuhang on 15/12/7.
*/
public class CrashHandler implements UncaughtExceptionHandler {

//系统默认的UncaughtException处理类
private Thread.UncaughtExceptionHandler mDefaultHandler;
//CrashHandler实例
private static CrashHandler INSTANCE;
//程序的Context对象
private Context mContext;
//用来存储设备信息和异常信息
private Map<String, String> infos = new HashMap<String, String>();

public CrashHandler() {
}

/**
* 获取CrashHandler实例 ,单例模式
*/
public static CrashHandler getInstance() {
if (INSTANCE == null)
INSTANCE = new CrashHandler();
return INSTANCE;
}

/**
* 初始化
*
* @param context
*/
public void init(Context context) {
mContext = context;
//获取系统默认的UncaughtException处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
//设置该CrashHandler为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}

/**
* 当UncaughtException发生时会转入该函数来处理
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
//如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
} else {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
LogUtils.e(e.toString());
}
//退出程序
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
}

/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
*
* @param ex
* @return true:如果处理了该异常信息;否则返回false.
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
//收集设备参数信息
collectDeviceInfo(mContext);
//保存日志文件
saveCrashInfo2File(ex);
return true;
}

/**
* 收集设备参数信息
*
* @param ctx
*/
public void collectDeviceInfo(Context ctx) {
try {
PackageManager pm = ctx.getPackageManager();
PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = pi.versionName == null ? "null" : pi.versionName;
String versionCode = pi.versionCode + "";
infos.put("versionName", versionName);
infos.put("versionCode", versionCode);
}
} catch (NameNotFoundException e) {
LogUtils.e("CrashHandleran.NameNotFoundException---> error occured when collect package info", e);
}
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
infos.put(field.getName(), field.get(null).toString());
} catch (Exception e) {
LogUtils.e("CrashHandler.NameNotFoundException---> an error occured when collect crash info", e);
}
}
}

/**
* 保存错误信息到文件中
*
* @param ex
* @return 返回文件名称, 便于将文件传送到服务器
*/
private String saveCrashInfo2File(Throwable ex) {

StringBuffer sb = new StringBuffer();
sb.append("---------------------sta--------------------------");
for (Map.Entry<String, String> entry : infos.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key + "=" + value + "\n");
}

Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String result = writer.toString();
sb.append(result);
sb.append("--------------------end---------------------------");
LogUtils.e(sb.toString());
return null;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android