android小技巧
2017-06-29 14:40
260 查看
1. 布局技巧
父布局居中
多余字不显示
字体太大时避免显示不全
子控件可以设置为全局固定。可用于实现布局滚动,折叠效果且要求固定Toolbar时
toolbar偏移量为0
横竖屏切换及editTextview键盘出现时视图不再上移
2. 可复用toolbar
nav_toolbar.xml
layout中引用
java调用
initToolbar();
3.沉浸式状态栏
4.通用BaseActivity
ParentActivity
MainActivity
SysApplication
CrashHandler.java
父布局居中
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; } }
相关文章推荐
- 如何用eclipse配置android开发环境——windows小技巧3
- 关于android图片加载框架univser-imageloader使用的一些小技巧记录
- Android之WebView使用小技巧
- Android Studio插件和一些小技巧
- android 初学之XML小技巧小结---自适应各种分辨率屏幕
- Android小技巧
- android小技巧
- android 调试的一些小技巧
- android 系统定制的小技巧
- Android小技巧 Part II——软键盘遮挡登录按钮
- Android使用ViewPager实现滚动广告解决OOM小技巧
- android使用百度地图SDK 去掉百度Logo的小技巧
- Android之实现遮罩动画的小技巧 类似flash遮罩动画
- Android小技巧(一):实现捕获应用的运行时异常
- Android开发中的小技巧
- Android 关于页卡布局的一个小技巧---如何在当前页刷新数据
- Android Snackbar使用方法及小技巧-design
- Android开发小技巧整理(持续更新)
- 分享几点Android 开发中的小技巧
- Android小技巧 如此简单就跳转了页面