开源库:
1、6.0权限库:RxPermissions:https://www.jianshu.com/p/c8a30200e6b2
2、Rx2网络封装:RxHttpUtils
3、Glide图片加载库:Glide:https://blog.youkuaiyun.com/column/details/15318.html
4、下拉刷新库: SmartRefreshLayout
5、RecyclerView简化框架:BaseRecyclerViewAdapterHelper
6、MD风格Dialog:material-dialogs :https://blog.youkuaiyun.com/qq_39652726/article/details/81262061
关于ViewPager.setOffscreenPageLimit()
Android中用ViewPager和Fragment内嵌WebView
WebView很好很强大,但是在Android中加载慢啊。
在同一个Activity中,用ViewPager可以加载多个Fragment,切换视图比较流畅,但是如果超出了3个Fragment,而且刚好Fragment中有WebView,体验就非常糟糕,页面要好几秒才能显示出来。
这是因为ViewPager缺省情况下,只把当前页的前一页和后一页放在缓冲区中。如果超出了3个Fragment,那么切换到第4个时,第一个会被销毁,第4个需要重建。内嵌的WebView就要重新被加载。
如果Frragment不是很多的话,那可以设置ViewPager.setOffscreenPageLimit,增加缓冲页面,避免WebView被重建。例如有4页,可以设置setOffscreenPageLimit(2),保持当前页的前两页和后两页。
巧的是,由于ViewPager可以预先加载和缓存fragment,避免了fragment中的WebView被无谓地刷新,体验反而更流畅了。如果WebView不在首页,那和原生开发的视图更没有太大区别。
在图片的指定位置添加标记
参考:https://blog.youkuaiyun.com/zuiwuyuan/article/details/52105176
当组件xml中通过 match_parent之类设了宽高,代码中获取宽高
//获取宽高--layout:实例化之后的组件
ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int height= layout.getHeight();
int width= layout.getWidth();
}
});
简单ListView适配
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,getData());
lv.setAdapter(adapter);
//初始化数据
public List<String> getData() {
ArrayList<String> data = new ArrayList<>();
for (int i = 0; i < 5; i++) {
data.add("number..." + i);
}
return data;
}
Fragment间传数据
基础配置:
// ======================= MainActivity ======================================
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frag_main);
MenuFragment menuFragment = new MenuFragment();
MainFragment mainFragment = new MainFragment();
//将上面的两个Fragment添加进来
getSupportFragmentManager().beginTransaction().replace(R.id.fl_menu, menuFragment, "menuFragment").commit();
getSupportFragmentManager().beginTransaction().replace(R.id.fl_main, mainFragment, "mainFragment").commit();
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<FrameLayout
android:id="@+id/fl_menu"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#20ff0000" />
<FrameLayout
android:id="@+id/fl_main"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="#2500ff00" />
</LinearLayout>
// ========================= MenuFragment =============================
public class MenuFragment extends Fragment {
ArrayList<String> data = new ArrayList<>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.menu,container,false);
ListView lv = (ListView) view.findViewById(R.id.lv_menu);
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(),android.R.layout.simple_list_item_1,getData());
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
return view;
}
//初始化数据
public List<String> getData() {
for (int i = 0; i < 5; i++) {
data.add("number..." + i);
}
return data;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/lv_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
// ============================ MainFragment ============================
public class MainFragment extends Fragment {
private Button bt_main;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main,container,false);
bt_main = (Button) view.findViewById(R.id.bt_main);
return view;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/bt_main"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
android:background="#ff0"
android:text="根据条目改变内容" />
</LinearLayout>
方法一:
// ===================== MenuFragment ===================
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
MainFragment mainFragment = (MainFragment) getActivity().getSupportFragmentManager().findFragmentByTag("mainFragment");
mainFragment.setData(data.get(position));
}
});
// ====================== MainFragment ====================
public void setData(String string) {
bt_main.setText(string);
}
方法二:
// ==================== MenuFragment =====================
public OnDataTransmissionListener mListener;
public interface OnDataTransmissionListener {
public void dataTransmission(String data);
}
public void setOnDataTransmissionListener(OnDataTransmissionListener mListener) {
this.mListener = mListener;
}
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mListener != null) {
mListener.dataTransmission(data.get(position));
}
}
});
// ==================== MainFragment=====================
public void setData(String string) {
bt_main.setText(string);
}
// ==================== MainActivity=====================
menuFragment.setOnDataTransmissionListener(new MenuFragment.OnDataTransmissionListener() {
@Override
public void dataTransmission(String data) {
mainFragment.setData(data);
}
});
方法三:
使用三方开源框架:EventBus
EventBus是一款针对Android优化的发布/订阅(publish/subscribe)事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息。简化了应用程序内各组件间、组件与后台线程间的通信。优点是开销小,代码更优雅,以及将发送者和接收者解耦。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。
AndroidStudio 在 lib 中添加jar包、so文件
右击jar包,选择add as lib,然后选择app module,当可以看到该jar包下内容时,表示添加成功了
main目录下创建文件jniLibs,把so库添加到其中
当报so库找不到时,可能是因为没有添加到匹配的so库文件夹中
Activity、Fragment状态保存和恢复
Activity:
当配置发生变化时,onSavaInstanceState会被调用,可以通过outState来保存数据和状态
当activity重建时,onRestoreInstanceState会被调用,利用其参数恢复状态
在onCreate中也可用于恢复数据,其 savedInstanceState 参数和 onRestoreInstanceState是一样的
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
Fragment:
排序
// 冒泡排序
public void sort(int[] arr) {
for(int j = 0; j < arr.length -1; j ++) {
for(int i = 0; i < arr.length-1; i ++) {
if(arr[i] > arr[i + 1]) {
int a = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = a;
}
}
}
showArray(arr);
}
// 直接选择排序
public void sort2(int[] arr) {
int index;
for(int j = 1; j < arr.length; j ++) {
index = 0;
for(int i = 1; i <= arr.length - j; i ++) {
if(arr[i] > arr[index]) {
index = i;
}
}
int a = arr[index];
arr[index] = arr[arr.length-j];
arr[arr.length-j] = a;
}
showArray(arr);
}
// 反转排序
public void sort3(int[] arr) {
for(int i = 0; i < arr.length/2; i ++) {
int temp = arr[i];
arr[i] = arr[arr.length-1 - i];
arr[arr.length - 1-i] = temp;
}
showArray(arr);
}
public void showArray(int[] arr) {
for(int i:arr) {
System.out.println(">"+i);
}
}
遍历
// List遍历
public void lists() {
Collection<String> list = new ArrayList<>();
list.add("asd");
list.add("qwe");
list.add("zxc");
Iterator<String> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
// Map遍历
public void maps() {
Map<String,String> map = new HashMap<>();
map.put("01", "李同学");
map.put("02", "网同学");
map.put("03", "张同学");
// 所有key的集合
Set<String> keys = map.keySet();
Iterator<String> it = keys.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
// 所有value的集合
Collection<String> values = map.values();
Iterator<String> its = values.iterator();
while(its.hasNext()) {
System.out.println(its.next());
}
}
讯飞 离线命令词识别 报错--
23108
1.Settings->应用程序->“你的应用程序”->权限->打开存储空间
2.添加了 WRITE_SETTINGS 权限,运行成功也是会报运行错误,但不影响运行就行,如果运行都不行的话,检查 jniLibs 中配置,参差配下搭配,有可能会是因为一个包写了或没写,暂时运行有用的搭配:
20006
Settings->应用程序->“你的应用程序”->权限->打开麦克风权限