diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..081b737fd --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 数据源本地存储已忽略文件 +/dataSources/ +/dataSources.local.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ diff --git a/.idea/Dokit.iml b/.idea/Dokit.iml new file mode 100644 index 000000000..d6ebd4805 --- /dev/null +++ b/.idea/Dokit.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 000000000..919ce1f1f --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 000000000..a55e7a179 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 000000000..69d1d89f9 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,32 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 000000000..6560a9898 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,36 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 000000000..c56cef51c --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 000000000..e94585c4d --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 000000000..00d3bd654 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Android/app/build.gradle b/Android/app/build.gradle index 3efa18f64..c2fef772a 100644 --- a/Android/app/build.gradle +++ b/Android/app/build.gradle @@ -200,11 +200,11 @@ dependencies { implementation rootProject.ext.dependencies["easypermissions"] releaseImplementation rootProject.ext.dependencies["okgo"] //高德地图定位 - implementation rootProject.ext.dependencies["amap_location"] +// implementation rootProject.ext.dependencies["amap_location"] //高德地图 // implementation rootProject.ext.dependencies["amap_map3d"] //高德搜索 - implementation rootProject.ext.dependencies["amap_search"] +// implementation rootProject.ext.dependencies["amap_search"] implementation rootProject.ext.dependencies["amap_navi"] //腾讯地图定位 // implementation rootProject.ext.dependencies["tencent_location"] diff --git a/Android/dokit/src/main/AndroidManifest.xml b/Android/dokit/src/main/AndroidManifest.xml index df38c255c..02e27445b 100644 --- a/Android/dokit/src/main/AndroidManifest.xml +++ b/Android/dokit/src/main/AndroidManifest.xml @@ -53,7 +53,9 @@ android:name=".kit.connect.DoKitScanActivity" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|stateUnchanged" /> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Android/dokit/src/main/assets/dokit_system_kits.json b/Android/dokit/src/main/assets/dokit_system_kits.json index f0ba72a1a..c883a8504 100644 --- a/Android/dokit/src/main/assets/dokit_system_kits.json +++ b/Android/dokit/src/main/assets/dokit_system_kits.json @@ -96,7 +96,12 @@ "allClassName": "com.didichuxing.doraemonkit.kit.h5_help.H5Kit", "checked": true, "innerKitId": "dokit_sdk_comm_ck_h5kit" - } + }, + { + "allClassName": "com.didichuxing.doraemonkit.kit.permissionlist.PermissionListKit", + "checked": true, + "innerKitId": "dokit_sdk_platform_ck_permission" + } ] }, { diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/BaseViewHolder.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/BaseViewHolder.java new file mode 100644 index 000000000..01a49a37e --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/BaseViewHolder.java @@ -0,0 +1,141 @@ +package com.didichuxing.doraemonkit.kit.permissionlist; + +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.util.SparseArray; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.databinding.DataBindingUtil; +import androidx.databinding.ViewDataBinding; +import androidx.recyclerview.widget.RecyclerView; + +/** + * 通用的RecyclerView.ViewHolder。提供了根据viewId获取View的方法。 + * 提供了对View、TextView、ImageView的常用设置方法。 + */ +public class BaseViewHolder extends RecyclerView.ViewHolder { + + private SparseArray mViews; + public boolean isExpanded; + + public BaseViewHolder(View itemView) { + super(itemView); + mViews = new SparseArray<>(); + isExpanded=false; + } + + /** + * 设置、查看子项是否扩展 + * @return + */ + public boolean isExpanded() { + return isExpanded; + } + + public void setExpanded(boolean expanded) { + isExpanded = expanded; + } + + + /** + * 获取item对应的ViewDataBinding对象 + * + * @param + * @return + */ + public T getBinding() { + return DataBindingUtil.getBinding(this.itemView); + } + + /** + * 根据View Id 获取对应的View + * + * @param viewId + * @param + * @return + */ + public T get(int viewId) { + View view = mViews.get(viewId); + if (view == null) { + view = this.itemView.findViewById(viewId); + mViews.put(viewId, view); + } + return (T) view; + } + + //******** 提供对View、TextView、ImageView的常用设置方法 ******// + public String getText(int viewId) { + TextView tv = get(viewId); + return tv.getText().toString(); + } + + public BaseViewHolder setText(int viewId, CharSequence text) { + TextView tv = get(viewId); + tv.setText(text); + return this; + } + + public BaseViewHolder setText(int viewId, int textRes) { + TextView tv = get(viewId); + tv.setText(textRes); + return this; + } + + public BaseViewHolder setTextColor(int viewId, int textColor) { + TextView view = get(viewId); + view.setTextColor(textColor); + return this; + } + + public BaseViewHolder setTextSize(int viewId, float size) { + TextView view = get(viewId); + view.setTextSize(size); + return this; + } + + public BaseViewHolder setImageResource(int viewId, int resId) { + ImageView view = get(viewId); + view.setImageResource(resId); + return this; + } + + public BaseViewHolder setImageBitmap(int viewId, Bitmap bitmap) { + ImageView view = get(viewId); + view.setImageBitmap(bitmap); + return this; + } + + + public BaseViewHolder setImageDrawable(int viewId, Drawable drawable) { + ImageView view = get(viewId); + view.setImageDrawable(drawable); + return this; + } + + + public BaseViewHolder setBackgroundColor(int viewId, int color) { + View view = get(viewId); + view.setBackgroundColor(color); + return this; + } + + public BaseViewHolder setBackgroundRes(int viewId, int backgroundRes) { + View view = get(viewId); + view.setBackgroundResource(backgroundRes); + return this; + } + + public BaseViewHolder setVisible(int viewId, boolean visible) { + View view = get(viewId); + view.setVisibility(visible ? View.VISIBLE : View.GONE); + return this; + } + + public BaseViewHolder setVisible(int viewId, int visible) { + View view = get(viewId); + view.setVisibility(visible); + return this; + } +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/ExpandableActivity.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/ExpandableActivity.java new file mode 100644 index 000000000..8dea08833 --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/ExpandableActivity.java @@ -0,0 +1,185 @@ +package com.didichuxing.doraemonkit.kit.permissionlist; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PermissionGroupInfo; +import android.content.pm.PermissionInfo; +import android.graphics.Color; +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.didichuxing.doraemonkit.R; +import com.didichuxing.doraemonkit.widget.titlebar.HomeTitleBar; + + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +/** + * Created by lmh 2022/6/14 + */ +public class ExpandableActivity extends AppCompatActivity { + private HashMap permissonmap; //获取预处理的所有权限map + private ArrayList PermissionInfoList; //获取预处理的所有权限list + public ArrayList normalList; + public ArrayList signatureList; + public ArrayList dangerousList; + public ArrayList notclassfied; + + private RecyclerView rvList; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getSupportActionBar().hide(); //隐藏标题栏 + //获取分组的信息 + normalList=new ArrayList<>(); + signatureList=new ArrayList<>(); + dangerousList=new ArrayList<>(); + notclassfied=new ArrayList<>(); + XMLparser Infoparser=new XMLparser(); //分组预处理,取得是安卓9的系统源码xml文件 + InputStream path = null; + try { + path = getResources().getAssets().open("AndroidManifest_meta.xml"); + } catch (IOException e) { + e.printStackTrace(); + } + PermissionInfoList =Infoparser.parser(path); + permissonmap=Infoparser.getMap(); + try { + getUsesPermission(this.getPackageName()); //对包权限进行分类 + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + //设置adapter + setContentView(R.layout.dk_permission_list_activity_group_list); + HomeTitleBar titleBar = findViewById(R.id.title_bar); + titleBar.setListener(() -> finish()); + rvList = (RecyclerView) findViewById(R.id.rv_list); + rvList.setLayoutManager(new LinearLayoutManager(this)); + ArrayList>grouplist=new ArrayList<>(); + grouplist.add(normalList); + grouplist.add(signatureList); + grouplist.add(dangerousList); + grouplist.add(notclassfied); + ExpandableAdapter adapter = new ExpandableAdapter(this, GroupModel.getExpandableGroups(PermissionInfoList, + grouplist)); + adapter.setOnHeaderClickListener(new GroupedRecyclerViewAdapter.OnHeaderClickListener() { + @Override + public void onHeaderClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, + int groupPosition) { + ExpandableAdapter expandableAdapter = (ExpandableAdapter) adapter; + if (expandableAdapter.isExpand(groupPosition)) { + expandableAdapter.collapseGroup(groupPosition); + } else { + expandableAdapter.expandGroup(groupPosition); + } + } + }); + adapter.setOnChildClickListener(new GroupedRecyclerViewAdapter.OnChildClickListener() { + @Override + public void onChildClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, + int groupPosition, int childPosition) { +// Toast.makeText(ExpandableActivity.this, "子项:groupPosition = " + groupPosition+ ", childPosition = " + childPosition,Toast.LENGTH_LONG).show(); + if (!holder.isExpanded()) { //如果当前是缩小的 + holder.setBackgroundColor(R.id.all, Color.BLACK); + holder.setExpanded(true); + holder.setTextColor(R.id.tv_child,Color.WHITE); + if(holder.getText(R.id.p_group)!="notfound"){ + holder.setVisible(R.id.p_group,true); + holder.setTextColor(R.id.p_group,Color.WHITE); + } + holder.setVisible(R.id.p_label,true); + holder.setTextColor(R.id.p_label,Color.WHITE); + holder.setVisible(R.id.p_description,true); + holder.setTextColor(R.id.p_description,Color.WHITE); + } else { + holder.setTextColor(R.id.tv_child,Color.BLACK); + holder.setBackgroundColor(R.id.all,Color.WHITE); + holder.setExpanded(false); + holder.setVisible(R.id.p_group,false); + holder.setVisible(R.id.p_label,false); + holder.setVisible(R.id.p_description,false); + } + + } + }); + rvList.setAdapter(adapter); + + } + + public static void openActivity(Context context) { + Intent intent = new Intent(context, ExpandableActivity.class); + context.startActivity(intent); + } + private void getUsesPermission(String packageName) throws PackageManager.NameNotFoundException { + PackageManager packageManager=this.getPackageManager(); + PackageInfo packageInfo=packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); + String [] usesPermissionsArray=packageInfo.requestedPermissions; + System.out.println(usesPermissionsArray.length); + + for (int i = 0; i < usesPermissionsArray.length; i++) { + try { + //得到每个权限的名字,如:android.permission.INTERNET + String usesPermissionName=usesPermissionsArray[i]; + MyPermissionInfo p= permissonmap.get(usesPermissionName); + + //通过usesPermissionName获取该权限的详细信息 + PermissionInfo permissionInfo=packageManager.getPermissionInfo(usesPermissionName, 0); + //获取该权限的标签信息,比如:完全的网络访问权限 + String permissionLabel=permissionInfo.loadLabel(packageManager).toString(); + //获取该权限的详细描述信息,比如:允许该应用创建网络套接字和使用自定义网络协议 + //浏览器和其他某些应用提供了向互联网发送数据的途径,因此应用无需该权限即可向互联网发送数据. + String permissionDescription=permissionInfo.loadDescription(packageManager).toString(); + p.setDescription(permissionDescription); + p.setLabel(permissionLabel); + + if(checkname(p.getProtectionLevel(),"normal")){ + normalList.add(p); + } + else if(checkname(p.getProtectionLevel(),"signature ")){ + signatureList.add(p); + } + else { + dangerousList.add(p); + } + } catch (Exception e) { + // TODO: handle exception + String invalidname=usesPermissionsArray[i]; + System.out.println(invalidname+"is not found in package"); + if(permissonmap.containsKey(invalidname)){ + MyPermissionInfo p=permissonmap.get(invalidname); + if(checkname(p.getProtectionLevel(),"normal")){ + normalList.add(p); + } + else if(checkname(p.getProtectionLevel(),"signature")){ + signatureList.add(p); + } + else { + dangerousList.add(p); + } + } + else{ + MyPermissionInfo p=new MyPermissionInfo(invalidname,"","",""); + notclassfied.add(p); + } + } + } + } + public boolean checkname(String name,String element){ + if(name.indexOf(element)>-1){ + return true; + } + else { + return false; + } + } + +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/ExpandableAdapter.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/ExpandableAdapter.java new file mode 100644 index 000000000..0438c87d9 --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/ExpandableAdapter.java @@ -0,0 +1,163 @@ +package com.didichuxing.doraemonkit.kit.permissionlist; + +import android.content.Context; +import android.widget.ImageView; + +import com.didichuxing.doraemonkit.R; + + +import com.didichuxing.doraemonkit.kit.permissionlist.entity.ChildEntity; +import com.didichuxing.doraemonkit.kit.permissionlist.entity.ExpandableGroupEntity; + + +import java.util.ArrayList; + +/** + * 可展开收起的Adapter。他跟普通的{GroupedListAdapter}基本是一样的。 + * 它只是利用了{@link GroupedRecyclerViewAdapter}的 + * 删除一组里的所有子项{@link GroupedRecyclerViewAdapter#notifyChildrenRemoved(int)}} 和 + * 插入一组里的所有子项{@link GroupedRecyclerViewAdapter#notifyChildrenInserted(int)} + * 两个方法达到列表的展开和收起的效果。 + * 这种列表类似于{@link ExpandableListView}的效果。 + * 这里我把列表的组尾去掉是为了效果上更像ExpandableListView。 + */ +public class ExpandableAdapter extends GroupedRecyclerViewAdapter { + + private ArrayList mGroups; + + public ExpandableAdapter(Context context, ArrayList groups) { + super(context); + mGroups = groups; + } + + @Override + public int getGroupCount() { + return mGroups == null ? 0 : mGroups.size(); + } + + @Override + public int getChildrenCount(int groupPosition) { + //如果当前组收起,就直接返回0,否则才返回子项数。这是实现列表展开和收起的关键。 + if (!isExpand(groupPosition)) { + return 0; + } + ArrayList children = mGroups.get(groupPosition).getChildren(); + return children == null ? 0 : children.size(); + } + + @Override + public boolean hasHeader(int groupPosition) { + return true; + } + + @Override + public boolean hasFooter(int groupPosition) { + return false; + } + + @Override + public int getHeaderLayout(int viewType) { + return R.layout.dk_permission_list_adapter_expandable_header; + } + + @Override + public int getFooterLayout(int viewType) { + return 0; + } + + @Override + public int getChildLayout(int viewType) { + return R.layout.dk_permission_list_adapter_child; + } + + @Override + public void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition) { + ExpandableGroupEntity entity = mGroups.get(groupPosition); + holder.setText(R.id.tv_expandable_header, entity.getHeader()); + ImageView ivState = holder.get(R.id.iv_state); + if(entity.isExpand()){ + ivState.setRotation(90); + } else { + ivState.setRotation(0); + } + } + + @Override + public void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition) { + } + + @Override + public void onBindChildViewHolder(BaseViewHolder holder, int groupPosition, int childPosition) { + ChildEntity entity = mGroups.get(groupPosition).getChildren().get(childPosition); + holder.setText(R.id.tv_child, entity.getChild().getName()); + if(entity.getChild().getPermissionGroup()==""){ + holder.setText(R.id.p_group,"notfound"); + } + else{ + holder.setText(R.id.p_group, "Group: "+entity.getChild().getPermissionGroup()); + } + holder.setText(R.id.p_label, "Label: "+entity.getChild().getLabel()); + holder.setText(R.id.p_description, "Description: "+entity.getChild().getDescription()); + } + + /** + * 判断当前组是否展开 + * + * @param groupPosition + * @return + */ + public boolean isExpand(int groupPosition) { + ExpandableGroupEntity entity = mGroups.get(groupPosition); + return entity.isExpand(); + } + + /** + * 展开一个组 + * + * @param groupPosition + */ + public void expandGroup(int groupPosition) { + expandGroup(groupPosition, false); + } + + /** + * 展开一个组 + * + * @param groupPosition + * @param animate + */ + public void expandGroup(int groupPosition, boolean animate) { + ExpandableGroupEntity entity = mGroups.get(groupPosition); + entity.setExpand(true); + if (animate) { + notifyChildrenInserted(groupPosition); + } else { + notifyDataChanged(); + } + } + + /** + * 收起一个组 + * + * @param groupPosition + */ + public void collapseGroup(int groupPosition) { + collapseGroup(groupPosition, false); + } + + /** + * 收起一个组 + * + * @param groupPosition + * @param animate + */ + public void collapseGroup(int groupPosition, boolean animate) { + ExpandableGroupEntity entity = mGroups.get(groupPosition); + entity.setExpand(false); + if (animate) { + notifyChildrenRemoved(groupPosition); + } else { + notifyDataChanged(); + } + } +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/GroupModel.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/GroupModel.java new file mode 100644 index 000000000..c7592fcc0 --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/GroupModel.java @@ -0,0 +1,43 @@ +package com.didichuxing.doraemonkit.kit.permissionlist; + +import com.didichuxing.doraemonkit.kit.permissionlist.entity.ChildEntity; +import com.didichuxing.doraemonkit.kit.permissionlist.entity.ExpandableGroupEntity; + +import java.util.ArrayList; + +/** + * Depiction: + * Author: teach + * Date: 2017/3/20 15:51 + */ +public class GroupModel { + + /** + * 获取可展开收起的组列表数据(默认展开) + * + * @param PermissionInfoList 所有权限列表 + * @param grouplist 分类权限列表 + * @return + */ + public static ArrayList getExpandableGroups(ArrayList PermissionInfoList, + ArrayList> grouplist) { + String[] titlename=new String[]{"普通权限_normal","签名权限_signature","危险权限_dangerous","未分类权限"}; + int sum=0;//总权限数目 + for(ArrayList arr:grouplist){ + sum+=arr.size(); + } + ArrayList groups = new ArrayList<>(); + for (int i = 0; i < grouplist.size(); i++) { + ArrayList children = new ArrayList<>(); + ArrayList permissionlist=grouplist.get(i); + for (int j = 0; j < permissionlist.size(); j++) { + children.add(new ChildEntity(permissionlist.get(j))); + } + groups.add(new ExpandableGroupEntity(titlename[i]+" ("+permissionlist.size()+ + "/"+sum+")", + "", true, children)); + } + return groups; + } + +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/GroupStructure.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/GroupStructure.java new file mode 100644 index 000000000..6e7344577 --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/GroupStructure.java @@ -0,0 +1,44 @@ +package com.didichuxing.doraemonkit.kit.permissionlist; + + +/** + * 这个类是用来记录分组列表中组的结构的。 + * 通过GroupStructure记录每个组是否有头部,是否有尾部和子项的数量。从而能方便的计算 + * 列表的长度和每个组的组头、组尾和子项在列表中的位置。 + */ +public class GroupStructure { + + private boolean hasHeader; + private boolean hasFooter; + private int childrenCount; + + public GroupStructure(boolean hasHeader, boolean hasFooter, int childrenCount) { + this.hasHeader = hasHeader; + this.hasFooter = hasFooter; + this.childrenCount = childrenCount; + } + + public boolean hasHeader() { + return hasHeader; + } + + public void setHasHeader(boolean hasHeader) { + this.hasHeader = hasHeader; + } + + public boolean hasFooter() { + return hasFooter; + } + + public void setHasFooter(boolean hasFooter) { + this.hasFooter = hasFooter; + } + + public int getChildrenCount() { + return childrenCount; + } + + public void setChildrenCount(int childrenCount) { + this.childrenCount = childrenCount; + } +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/GroupedRecyclerViewAdapter.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/GroupedRecyclerViewAdapter.java new file mode 100644 index 000000000..89d854ae3 --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/GroupedRecyclerViewAdapter.java @@ -0,0 +1,1249 @@ +package com.didichuxing.doraemonkit.kit.permissionlist; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.widget.FrameLayout; + +import androidx.databinding.DataBindingUtil; +import androidx.databinding.ViewDataBinding; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.StaggeredGridLayoutManager; + +import com.didichuxing.doraemonkit.R; + +import java.util.ArrayList; + + +/** + * 通用的分组列表Adapter。通过它可以很方便的实现列表的分组效果。 + * 这个类提供了一系列的对列表的更新、删除和插入等操作的方法。 + * 使用者要使用这些方法的列表进行操作,而不要直接使用RecyclerView.Adapter的方法。 + * 因为当分组列表发生变化时,需要及时更新分组列表的组结构{@link GroupedRecyclerViewAdapter#mStructures} + */ +public abstract class GroupedRecyclerViewAdapter + extends RecyclerView.Adapter { + + public static final int TYPE_HEADER = R.integer.type_header; + public static final int TYPE_FOOTER = R.integer.type_footer; + public static final int TYPE_CHILD = R.integer.type_child; + public static final int TYPE_EMPTY = R.integer.type_empty; + + private OnHeaderClickListener mOnHeaderClickListener; + private OnFooterClickListener mOnFooterClickListener; + private OnChildClickListener mOnChildClickListener; + private OnHeaderLongClickListener mOnHeaderLongClickListener; + private OnFooterLongClickListener mOnFooterLongClickListener; + private OnChildLongClickListener mOnChildLongClickListener; + + protected Context mContext; + //保存分组列表的组结构 + protected ArrayList mStructures = new ArrayList<>(); + //数据是否发生变化。如果数据发生变化,要及时更新组结构。 + private boolean isDataChanged; + private int mTempPosition; + + private boolean mUseBinding; + + // 是否显示空布局 + private boolean showEmptyView = false; + + public GroupedRecyclerViewAdapter(Context context) { + this(context, false); + } + + public GroupedRecyclerViewAdapter(Context context, boolean useBinding) { + mContext = context; + mUseBinding = useBinding; + registerAdapterDataObserver(new GroupDataObserver()); + } + + @Override + public void onAttachedToRecyclerView(RecyclerView recyclerView) { + super.onAttachedToRecyclerView(recyclerView); + structureChanged(); + } + + @Override + public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { + super.onViewAttachedToWindow(holder); + + //处理StaggeredGridLayout,保证组头和组尾占满一行。 + if (isStaggeredGridLayout(holder)) { + handleLayoutIfStaggeredGridLayout(holder, holder.getLayoutPosition()); + } + } + + private boolean isStaggeredGridLayout(RecyclerView.ViewHolder holder) { + ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams(); + if (layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) { + return true; + } + return false; + } + + private void handleLayoutIfStaggeredGridLayout(RecyclerView.ViewHolder holder, int position) { + if (isEmptyPosition(position) || judgeType(position) == TYPE_HEADER || judgeType(position) == TYPE_FOOTER) { + StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) + holder.itemView.getLayoutParams(); + p.setFullSpan(true); + } + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if (viewType == TYPE_EMPTY) { + return new BaseViewHolder(getEmptyView(parent)); + } else { + if (mUseBinding) { + ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(mContext), + getLayoutId(mTempPosition, viewType), parent, false); + return new BaseViewHolder(binding.getRoot()); + } else { + View view = LayoutInflater.from(mContext).inflate( + getLayoutId(mTempPosition, viewType), parent, false); + return new BaseViewHolder(view); + } + } + } + + @Override + public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { + int type = judgeType(position); + final int groupPosition = getGroupPositionForPosition(position); + if (type == TYPE_HEADER) { + if (mOnHeaderClickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mOnHeaderClickListener != null) { + ViewParent parent = holder.itemView.getParent(); + int gPosition = parent instanceof FrameLayout ? groupPosition : getGroupPositionForPosition(holder.getLayoutPosition()); + if (gPosition >= 0 && gPosition < mStructures.size()) { + mOnHeaderClickListener.onHeaderClick(GroupedRecyclerViewAdapter.this, + (BaseViewHolder) holder, gPosition); + } + } + } + }); + } + + if (mOnHeaderLongClickListener != null) { + holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if (mOnHeaderLongClickListener != null) { + ViewParent parent = holder.itemView.getParent(); + int gPosition = parent instanceof FrameLayout ? groupPosition : getGroupPositionForPosition(holder.getLayoutPosition()); + if (gPosition >= 0 && gPosition < mStructures.size()) { + return mOnHeaderLongClickListener.onHeaderLongClick(GroupedRecyclerViewAdapter.this, + (BaseViewHolder) holder, gPosition); + } + } + return false; + } + }); + } + onBindHeaderViewHolder((BaseViewHolder) holder, groupPosition); + } else if (type == TYPE_FOOTER) { + if (mOnFooterClickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mOnFooterClickListener != null) { + int gPosition = getGroupPositionForPosition(holder.getLayoutPosition()); + if (gPosition >= 0 && gPosition < mStructures.size()) { + mOnFooterClickListener.onFooterClick(GroupedRecyclerViewAdapter.this, + (BaseViewHolder) holder, gPosition); + } + } + } + }); + } + + if (mOnFooterLongClickListener != null) { + holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if (mOnFooterLongClickListener != null) { + int gPosition = getGroupPositionForPosition(holder.getLayoutPosition()); + if (gPosition >= 0 && gPosition < mStructures.size()) { + return mOnFooterLongClickListener.onFooterLongClick(GroupedRecyclerViewAdapter.this, + (BaseViewHolder) holder, gPosition); + } + } + return false; + } + }); + } + onBindFooterViewHolder((BaseViewHolder) holder, groupPosition); + } else if (type == TYPE_CHILD) { + int childPosition = getChildPositionForPosition(groupPosition, position); + if (mOnChildClickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mOnChildClickListener != null) { + int gPosition = getGroupPositionForPosition(holder.getLayoutPosition()); + int cPosition = getChildPositionForPosition(gPosition, holder.getLayoutPosition()); + if (gPosition >= 0 && gPosition < mStructures.size() && cPosition >= 0 + && cPosition < mStructures.get(gPosition).getChildrenCount()) { + mOnChildClickListener.onChildClick(GroupedRecyclerViewAdapter.this, + (BaseViewHolder) holder, gPosition, cPosition); + } + } + } + }); + } + + if (mOnChildLongClickListener != null) { + holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if (mOnChildLongClickListener != null) { + int gPosition = getGroupPositionForPosition(holder.getLayoutPosition()); + int cPosition = getChildPositionForPosition(gPosition, holder.getLayoutPosition()); + if (gPosition >= 0 && gPosition < mStructures.size() && cPosition >= 0 + && cPosition < mStructures.get(gPosition).getChildrenCount()) { + return mOnChildLongClickListener.onChildLongClick(GroupedRecyclerViewAdapter.this, + (BaseViewHolder) holder, gPosition, cPosition); + } + } + return false; + } + }); + } + onBindChildViewHolder((BaseViewHolder) holder, groupPosition, childPosition); + } + } + + @Override + public int getItemCount() { + if (isDataChanged) { + structureChanged(); + } + + int count = count(); + if (count > 0) { + return count; + } else if (showEmptyView) { + // 显示空布局 + return 1; + } else { + return 0; + } + } + + public boolean isEmptyPosition(int position) { + return position == 0 && showEmptyView && count() == 0; + } + + @Override + public int getItemViewType(int position) { + if (isEmptyPosition(position)) { + // 空布局 + return TYPE_EMPTY; + } + mTempPosition = position; + int groupPosition = getGroupPositionForPosition(position); + int type = judgeType(position); + if (type == TYPE_HEADER) { + return getHeaderViewType(groupPosition); + } else if (type == TYPE_FOOTER) { + return getFooterViewType(groupPosition); + } else if (type == TYPE_CHILD) { + int childPosition = getChildPositionForPosition(groupPosition, position); + return getChildViewType(groupPosition, childPosition); + } + return super.getItemViewType(position); + } + + public int getHeaderViewType(int groupPosition) { + return TYPE_HEADER; + } + + public int getFooterViewType(int groupPosition) { + return TYPE_FOOTER; + } + + public int getChildViewType(int groupPosition, int childPosition) { + return TYPE_CHILD; + } + + private int getLayoutId(int position, int viewType) { + int type = judgeType(position); + if (type == TYPE_HEADER) { + return getHeaderLayout(viewType); + } else if (type == TYPE_FOOTER) { + return getFooterLayout(viewType); + } else if (type == TYPE_CHILD) { + return getChildLayout(viewType); + } + return 0; + } + + private int count() { + return countGroupRangeItem(0, mStructures.size()); + } + + /** + * 判断item的type 头部 尾部 和 子项 + * + * @param position + * @return + */ + public int judgeType(int position) { + int itemCount = 0; + int groupCount = mStructures.size(); + + for (int i = 0; i < groupCount; i++) { + GroupStructure structure = mStructures.get(i); + if (structure.hasHeader()) { + itemCount += 1; + if (position < itemCount) { + return TYPE_HEADER; + } + } + + itemCount += structure.getChildrenCount(); + if (position < itemCount) { + return TYPE_CHILD; + } + + if (structure.hasFooter()) { + itemCount += 1; + if (position < itemCount) { + return TYPE_FOOTER; + } + } + } + + return TYPE_EMPTY; + } + + /** + * 重置组结构列表 + */ + private void structureChanged() { + mStructures.clear(); + int groupCount = getGroupCount(); + for (int i = 0; i < groupCount; i++) { + mStructures.add(new GroupStructure(hasHeader(i), hasFooter(i), getChildrenCount(i))); + } + isDataChanged = false; + } + + /** + * 根据下标计算position所在的组(groupPosition) + * + * @param position 下标 + * @return 组下标 groupPosition + */ + public int getGroupPositionForPosition(int position) { + int count = 0; + int groupCount = mStructures.size(); + for (int i = 0; i < groupCount; i++) { + count += countGroupItem(i); + if (position < count) { + return i; + } + } + return -1; + } + + /** + * 根据下标计算position在组中位置(childPosition) + * + * @param groupPosition 所在的组 + * @param position 下标 + * @return 子项下标 childPosition + */ + public int getChildPositionForPosition(int groupPosition, int position) { + if (groupPosition >= 0 && groupPosition < mStructures.size()) { + int itemCount = countGroupRangeItem(0, groupPosition + 1); + GroupStructure structure = mStructures.get(groupPosition); + int p = structure.getChildrenCount() - (itemCount - position) + + (structure.hasFooter() ? 1 : 0); + if (p >= 0) { + return p; + } + } + return -1; + } + + /** + * 获取一个组的开始下标,这个下标可能是组头,可能是子项(如果没有组头)或者组尾(如果这个组只有组尾) + * + * @param groupPosition 组下标 + * @return + */ + public int getPositionForGroup(int groupPosition) { + if (groupPosition >= 0 && groupPosition < mStructures.size()) { + return countGroupRangeItem(0, groupPosition); + } else { + return -1; + } + + } + + /** + * 获取一个组的组头下标 如果该组没有组头 返回-1 + * + * @param groupPosition 组下标 + * @return 下标 + */ + public int getPositionForGroupHeader(int groupPosition) { + if (groupPosition >= 0 && groupPosition < mStructures.size()) { + GroupStructure structure = mStructures.get(groupPosition); + if (!structure.hasHeader()) { + return -1; + } + return countGroupRangeItem(0, groupPosition); + } + return -1; + } + + /** + * 获取一个组的组尾下标 如果该组没有组尾 返回-1 + * + * @param groupPosition 组下标 + * @return 下标 + */ + public int getPositionForGroupFooter(int groupPosition) { + if (groupPosition >= 0 && groupPosition < mStructures.size()) { + GroupStructure structure = mStructures.get(groupPosition); + if (!structure.hasFooter()) { + return -1; + } + return countGroupRangeItem(0, groupPosition + 1) - 1; + } + return -1; + } + + /** + * 获取一个组指定的子项下标 如果没有 返回-1 + * + * @param groupPosition 组下标 + * @param childPosition 子项的组内下标 + * @return 下标 + */ + public int getPositionForChild(int groupPosition, int childPosition) { + if (groupPosition >= 0 && groupPosition < mStructures.size()) { + GroupStructure structure = mStructures.get(groupPosition); + if (structure.getChildrenCount() > childPosition) { + int itemCount = countGroupRangeItem(0, groupPosition); + return itemCount + childPosition + (structure.hasHeader() ? 1 : 0); + } + } + return -1; + } + + /** + * 计算一个组里有多少个Item(头加尾加子项) + * + * @param groupPosition + * @return + */ + public int countGroupItem(int groupPosition) { + int itemCount = 0; + if (groupPosition >= 0 && groupPosition < mStructures.size()) { + GroupStructure structure = mStructures.get(groupPosition); + if (structure.hasHeader()) { + itemCount += 1; + } + itemCount += structure.getChildrenCount(); + if (structure.hasFooter()) { + itemCount += 1; + } + } + return itemCount; + } + + /** + * 计算多个组的项的总和 + * + * @return + */ + public int countGroupRangeItem(int start, int count) { + int itemCount = 0; + int size = mStructures.size(); + for (int i = start; i < size && i < start + count; i++) { + itemCount += countGroupItem(i); + } + return itemCount; + } + + /** + * 设置空布局显示。默认不显示 + * + * @param isShow + */ + public void showEmptyView(boolean isShow) { + if (isShow != showEmptyView) { + showEmptyView = isShow; + notifyDataChanged(); + } + } + + public boolean isShowEmptyView() { + return showEmptyView; + } + + //****** 刷新操作 *****// + + /** + * Use {@link #notifyDataChanged()} instead. + */ + @Deprecated + public void changeDataSet() { + notifyDataChanged(); + } + + /** + * 通知数据列表刷新 + */ + public void notifyDataChanged() { + isDataChanged = true; + notifyDataSetChanged(); + } + + /** + * Use {@link #notifyGroupChanged(int)} instead. + * + * @param groupPosition + */ + @Deprecated + public void changeGroup(int groupPosition) { + notifyGroupChanged(groupPosition); + } + + /** + * 通知一组数据刷新,包括组头,组尾和子项 + * + * @param groupPosition + */ + public void notifyGroupChanged(int groupPosition) { + int index = getPositionForGroup(groupPosition); + int itemCount = countGroupItem(groupPosition); + if (index >= 0 && itemCount > 0) { + notifyItemRangeChanged(index, itemCount); + } + } + + /** + * Use {@link #notifyGroupRangeChanged(int, int)} instead. + * + * @param groupPosition + * @param count + */ + @Deprecated + public void changeRangeGroup(int groupPosition, int count) { + notifyGroupRangeChanged(groupPosition, count); + } + + /** + * 通知多组数据刷新,包括组头,组尾和子项 + * + * @param groupPosition + */ + public void notifyGroupRangeChanged(int groupPosition, int count) { + int index = getPositionForGroup(groupPosition); + int itemCount = 0; + if (groupPosition + count <= mStructures.size()) { + itemCount = countGroupRangeItem(groupPosition, groupPosition + count); + } else { + itemCount = countGroupRangeItem(groupPosition, mStructures.size()); + } + if (index >= 0 && itemCount > 0) { + notifyItemRangeChanged(index, itemCount); + } + } + + /** + * Use {@link #notifyHeaderChanged(int)} instead. + * + * @param groupPosition + */ + @Deprecated + public void changeHeader(int groupPosition) { + notifyHeaderChanged(groupPosition); + } + + /** + * 通知组头刷新 + * + * @param groupPosition + */ + public void notifyHeaderChanged(int groupPosition) { + int index = getPositionForGroupHeader(groupPosition); + if (index >= 0) { + notifyItemChanged(index); + } + } + + /** + * Use {@link #notifyFooterChanged(int)} instead. + * + * @param groupPosition + */ + @Deprecated + public void changeFooter(int groupPosition) { + notifyFooterChanged(groupPosition); + } + + /** + * 通知组尾刷新 + * + * @param groupPosition + */ + public void notifyFooterChanged(int groupPosition) { + int index = getPositionForGroupFooter(groupPosition); + if (index >= 0) { + notifyItemChanged(index); + } + } + + /** + * Use {@link #notifyChildChanged(int, int)} instead. + * + * @param groupPosition + * @param childPosition + */ + @Deprecated + public void changeChild(int groupPosition, int childPosition) { + notifyChildChanged(groupPosition, childPosition); + } + + /** + * 通知一组里的某个子项刷新 + * + * @param groupPosition + * @param childPosition + */ + public void notifyChildChanged(int groupPosition, int childPosition) { + int index = getPositionForChild(groupPosition, childPosition); + if (index >= 0) { + notifyItemChanged(index); + } + } + + /** + * Use {@link #notifyChildRangeChanged(int, int, int)} instead. + * + * @param groupPosition + * @param childPosition + * @param count + */ + @Deprecated + public void changeRangeChild(int groupPosition, int childPosition, int count) { + notifyChildRangeChanged(groupPosition, childPosition, count); + } + + /** + * 通知一组里的多个子项刷新 + * + * @param groupPosition + * @param childPosition + * @param count + */ + public void notifyChildRangeChanged(int groupPosition, int childPosition, int count) { + if (groupPosition < mStructures.size()) { + int index = getPositionForChild(groupPosition, childPosition); + if (index >= 0) { + GroupStructure structure = mStructures.get(groupPosition); + if (structure.getChildrenCount() >= childPosition + count) { + notifyItemRangeChanged(index, count); + } else { + notifyItemRangeChanged(index, structure.getChildrenCount() - childPosition); + } + } + } + } + + /** + * Use {@link #notifyChildrenChanged(int)} instead. + * + * @param groupPosition + */ + @Deprecated + public void changeChildren(int groupPosition) { + notifyChildrenChanged(groupPosition); + } + + /** + * 通知一组里的所有子项刷新 + * + * @param groupPosition + */ + public void notifyChildrenChanged(int groupPosition) { + if (groupPosition >= 0 && groupPosition < mStructures.size()) { + int index = getPositionForChild(groupPosition, 0); + if (index >= 0) { + GroupStructure structure = mStructures.get(groupPosition); + notifyItemRangeChanged(index, structure.getChildrenCount()); + } + } + } + + //****** 删除操作 *****// + + /** + * Use {@link #notifyDataRemoved()} instead. + */ + @Deprecated + public void removeAll() { + notifyDataRemoved(); + } + + /** + * 通知所有数据删除 + */ + public void notifyDataRemoved() { + int count = countGroupRangeItem(0, mStructures.size()); + mStructures.clear(); + notifyItemRangeRemoved(0, count); + } + + /** + * Use {@link #notifyGroupRemoved(int)} instead. + */ + @Deprecated + public void removeGroup(int groupPosition) { + notifyGroupRemoved(groupPosition); + } + + /** + * 通知一组数据删除,包括组头,组尾和子项 + * + * @param groupPosition + */ + public void notifyGroupRemoved(int groupPosition) { + int index = getPositionForGroup(groupPosition); + int itemCount = countGroupItem(groupPosition); + if (index >= 0 && itemCount > 0) { + mStructures.remove(groupPosition); + notifyItemRangeRemoved(index, itemCount); + } + } + + /** + * Use {@link #notifyGroupRangeRemoved(int, int)} instead. + */ + @Deprecated + public void removeRangeGroup(int groupPosition, int count) { + notifyGroupRangeRemoved(groupPosition, count); + } + + /** + * 通知多组数据删除,包括组头,组尾和子项 + * + * @param groupPosition + */ + public void notifyGroupRangeRemoved(int groupPosition, int count) { + int index = getPositionForGroup(groupPosition); + int itemCount = 0; + if (groupPosition + count <= mStructures.size()) { + itemCount = countGroupRangeItem(groupPosition, groupPosition + count); + } else { + itemCount = countGroupRangeItem(groupPosition, mStructures.size()); + } + if (index >= 0 && itemCount > 0) { + mStructures.remove(groupPosition); + notifyItemRangeRemoved(index, itemCount); + } + } + + /** + * Use {@link #notifyHeaderRemoved(int)} instead. + */ + @Deprecated + public void removeHeader(int groupPosition) { + notifyHeaderRemoved(groupPosition); + } + + /** + * 通知组头删除 + * + * @param groupPosition + */ + public void notifyHeaderRemoved(int groupPosition) { + int index = getPositionForGroupHeader(groupPosition); + if (index >= 0) { + GroupStructure structure = mStructures.get(groupPosition); + structure.setHasHeader(false); + notifyItemRemoved(index); + } + } + + /** + * Use {@link #notifyFooterRemoved(int)} instead. + * + * @param groupPosition + */ + @Deprecated + public void removeFooter(int groupPosition) { + notifyFooterRemoved(groupPosition); + } + + /** + * 通知组尾删除 + * + * @param groupPosition + */ + public void notifyFooterRemoved(int groupPosition) { + int index = getPositionForGroupFooter(groupPosition); + if (index >= 0) { + GroupStructure structure = mStructures.get(groupPosition); + structure.setHasFooter(false); + notifyItemRemoved(index); + } + } + + /** + * Use {@link #notifyChildRemoved(int, int)} instead. + * + * @param groupPosition + * @param childPosition + */ + @Deprecated + public void removeChild(int groupPosition, int childPosition) { + notifyChildRemoved(groupPosition, childPosition); + } + + /** + * 通知一组里的某个子项删除 + * + * @param groupPosition + * @param childPosition + */ + public void notifyChildRemoved(int groupPosition, int childPosition) { + int index = getPositionForChild(groupPosition, childPosition); + if (index >= 0) { + GroupStructure structure = mStructures.get(groupPosition); + structure.setChildrenCount(structure.getChildrenCount() - 1); + notifyItemRemoved(index); + } + } + + /** + * Use {@link #notifyChildRangeRemoved(int, int, int)} instead. + * + * @param groupPosition + * @param childPosition + * @param count + */ + @Deprecated + public void removeRangeChild(int groupPosition, int childPosition, int count) { + notifyChildRangeRemoved(groupPosition, childPosition, count); + } + + /** + * 通知一组里的多个子项删除 + * + * @param groupPosition + * @param childPosition + * @param count + */ + public void notifyChildRangeRemoved(int groupPosition, int childPosition, int count) { + if (groupPosition < mStructures.size()) { + int index = getPositionForChild(groupPosition, childPosition); + if (index >= 0) { + GroupStructure structure = mStructures.get(groupPosition); + int childCount = structure.getChildrenCount(); + int removeCount = count; + if (childCount < childPosition + count) { + removeCount = childCount - childPosition; + } + structure.setChildrenCount(childCount - removeCount); + notifyItemRangeRemoved(index, removeCount); + } + } + } + + /** + * Use {@link #notifyChildrenRemoved(int)} instead. + * + * @param groupPosition + */ + @Deprecated + public void removeChildren(int groupPosition) { + notifyChildrenRemoved(groupPosition); + } + + /** + * 通知一组里的所有子项删除 + * + * @param groupPosition + */ + public void notifyChildrenRemoved(int groupPosition) { + if (groupPosition < mStructures.size()) { + int index = getPositionForChild(groupPosition, 0); + if (index >= 0) { + GroupStructure structure = mStructures.get(groupPosition); + int itemCount = structure.getChildrenCount(); + structure.setChildrenCount(0); + notifyItemRangeRemoved(index, itemCount); + } + } + } + + //****** 插入操作 *****// + + /** + * Use {@link #notifyGroupInserted(int)} instead. + * + * @param groupPosition + */ + @Deprecated + public void insertGroup(int groupPosition) { + notifyGroupInserted(groupPosition); + } + + /** + * 通知一组数据插入 + * + * @param groupPosition + */ + public void notifyGroupInserted(int groupPosition) { + GroupStructure structure = new GroupStructure(hasHeader(groupPosition), + hasFooter(groupPosition), getChildrenCount(groupPosition)); + if (groupPosition < mStructures.size()) { + mStructures.add(groupPosition, structure); + } else { + mStructures.add(structure); + groupPosition = mStructures.size() - 1; + } + + int index = countGroupRangeItem(0, groupPosition); + int itemCount = countGroupItem(groupPosition); + if (itemCount > 0) { + notifyItemRangeInserted(index, itemCount); + } + } + + /** + * Use {@link #notifyGroupRangeInserted(int, int)} instead. + * + * @param groupPosition + * @param count + */ + @Deprecated + public void insertRangeGroup(int groupPosition, int count) { + notifyGroupRangeInserted(groupPosition, count); + } + + /** + * 通知多组数据插入 + * + * @param groupPosition + * @param count + */ + public void notifyGroupRangeInserted(int groupPosition, int count) { + ArrayList list = new ArrayList<>(); + for (int i = 0; i < count; i++) { + GroupStructure structure = new GroupStructure(hasHeader(i), + hasFooter(i), getChildrenCount(i)); + list.add(structure); + } + + if (groupPosition < mStructures.size()) { + mStructures.addAll(groupPosition, list); + } else { + mStructures.addAll(list); + groupPosition = mStructures.size() - list.size(); + } + + int index = countGroupRangeItem(0, groupPosition); + int itemCount = countGroupRangeItem(groupPosition, count); + if (itemCount > 0) { + notifyItemRangeInserted(index, itemCount); + } + } + + /** + * Use {@link #notifyHeaderInserted(int)} instead. + * + * @param groupPosition + */ + @Deprecated + public void insertHeader(int groupPosition) { + notifyHeaderInserted(groupPosition); + } + + /** + * 通知组头插入 + * + * @param groupPosition + */ + public void notifyHeaderInserted(int groupPosition) { + if (groupPosition < mStructures.size() && 0 > getPositionForGroupHeader(groupPosition)) { + GroupStructure structure = mStructures.get(groupPosition); + structure.setHasHeader(true); + int index = countGroupRangeItem(0, groupPosition); + notifyItemInserted(index); + } + } + + /** + * Use {@link #notifyFooterInserted(int)} instead. + * + * @param groupPosition + */ + @Deprecated + public void insertFooter(int groupPosition) { + notifyFooterInserted(groupPosition); + } + + /** + * 通知组尾插入 + * + * @param groupPosition + */ + public void notifyFooterInserted(int groupPosition) { + if (groupPosition < mStructures.size() && 0 > getPositionForGroupFooter(groupPosition)) { + GroupStructure structure = mStructures.get(groupPosition); + structure.setHasFooter(true); + int index = countGroupRangeItem(0, groupPosition + 1); + notifyItemInserted(index); + } + } + + /** + * Use {@link #notifyChildInserted(int, int)} instead. + * + * @param groupPosition + * @param childPosition + */ + @Deprecated + public void insertChild(int groupPosition, int childPosition) { + notifyChildInserted(groupPosition, childPosition); + } + + /** + * 通知一个子项到组里插入 + * + * @param groupPosition + * @param childPosition + */ + public void notifyChildInserted(int groupPosition, int childPosition) { + if (groupPosition < mStructures.size()) { + GroupStructure structure = mStructures.get(groupPosition); + int index = getPositionForChild(groupPosition, childPosition); + if (index < 0) { + index = countGroupRangeItem(0, groupPosition); + index += structure.hasHeader() ? 1 : 0; + index += structure.getChildrenCount(); + } + structure.setChildrenCount(structure.getChildrenCount() + 1); + notifyItemInserted(index); + } + } + + /** + * Use {@link #notifyChildRangeInserted(int, int, int)} instead. + * + * @param groupPosition + * @param childPosition + * @param count + */ + @Deprecated + public void insertRangeChild(int groupPosition, int childPosition, int count) { + notifyChildRangeInserted(groupPosition, childPosition, count); + } + + /** + * 通知一组里的多个子项插入 + * + * @param groupPosition + * @param childPosition + * @param count + */ + public void notifyChildRangeInserted(int groupPosition, int childPosition, int count) { + if (groupPosition < mStructures.size()) { + int index = countGroupRangeItem(0, groupPosition); + GroupStructure structure = mStructures.get(groupPosition); + if (structure.hasHeader()) { + index++; + } + if (childPosition < structure.getChildrenCount()) { + index += childPosition; + } else { + index += structure.getChildrenCount(); + } + if (count > 0) { + structure.setChildrenCount(structure.getChildrenCount() + count); + notifyItemRangeInserted(index, count); + } + } + } + + /** + * Use {@link #notifyChildrenInserted(int)} instead. + * + * @param groupPosition + */ + @Deprecated + public void insertChildren(int groupPosition) { + notifyChildrenInserted(groupPosition); + } + + /** + * 通知一组里的所有子项插入 + * + * @param groupPosition + */ + public void notifyChildrenInserted(int groupPosition) { + if (groupPosition < mStructures.size()) { + int index = countGroupRangeItem(0, groupPosition); + GroupStructure structure = mStructures.get(groupPosition); + if (structure.hasHeader()) { + index++; + } + int itemCount = getChildrenCount(groupPosition); + if (itemCount > 0) { + structure.setChildrenCount(itemCount); + notifyItemRangeInserted(index, itemCount); + } + } + } + + //****** 设置点击事件 *****// + + /** + * 设置组头点击事件 + * + * @param listener + */ + public void setOnHeaderClickListener(OnHeaderClickListener listener) { + mOnHeaderClickListener = listener; + } + + /** + * 设置组尾点击事件 + * + * @param listener + */ + public void setOnFooterClickListener(OnFooterClickListener listener) { + mOnFooterClickListener = listener; + } + + /** + * 设置子项长按事件 + * + * @param listener + */ + public void setOnChildLongClickListener(OnChildLongClickListener listener) { + mOnChildLongClickListener = listener; + } + + /** + * 设置组头长按事件 + * + * @param listener + */ + public void setOnHeaderLongClickListener(OnHeaderLongClickListener listener) { + mOnHeaderLongClickListener = listener; + } + + /** + * 设置组尾长按事件 + * + * @param listener + */ + public void setOnFooterLongClickListener(OnFooterLongClickListener listener) { + mOnFooterLongClickListener = listener; + } + + /** + * 设置子项点击事件 + * + * @param listener + */ + public void setOnChildClickListener(OnChildClickListener listener) { + mOnChildClickListener = listener; + } + + public abstract int getGroupCount(); + + public abstract int getChildrenCount(int groupPosition); + + public abstract boolean hasHeader(int groupPosition); + + public abstract boolean hasFooter(int groupPosition); + + public abstract int getHeaderLayout(int viewType); + + public abstract int getFooterLayout(int viewType); + + public abstract int getChildLayout(int viewType); + + public abstract void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition); + + public abstract void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition); + + public abstract void onBindChildViewHolder(BaseViewHolder holder, + int groupPosition, int childPosition); + + /** + * 获取空布局 + * + * @param parent + * @return + */ + public View getEmptyView(ViewGroup parent) { + View view = LayoutInflater.from(mContext).inflate(R.layout.dk_permission_list_group_adapter_default_empty_view, parent, false); + return view; + } + + class GroupDataObserver extends RecyclerView.AdapterDataObserver { + + @Override + public void onChanged() { + isDataChanged = true; + } + + public void onItemRangeChanged(int positionStart, int itemCount) { + isDataChanged = true; + } + + public void onItemRangeChanged(int positionStart, int itemCount, Object payload) { + onItemRangeChanged(positionStart, itemCount); + } + + public void onItemRangeInserted(int positionStart, int itemCount) { + isDataChanged = true; + } + + public void onItemRangeRemoved(int positionStart, int itemCount) { + isDataChanged = true; + } + } + + public interface OnHeaderClickListener { + void onHeaderClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, int groupPosition); + } + + public interface OnFooterClickListener { + void onFooterClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, int groupPosition); + } + + public interface OnChildClickListener { + void onChildClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, + int groupPosition, int childPosition); + } + + public interface OnHeaderLongClickListener { + boolean onHeaderLongClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, int groupPosition); + } + + public interface OnFooterLongClickListener { + boolean onFooterLongClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, int groupPosition); + } + + public interface OnChildLongClickListener { + boolean onChildLongClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, + int groupPosition, int childPosition); + } +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/MyPermissionInfo.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/MyPermissionInfo.java new file mode 100644 index 000000000..8c6f777b4 --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/MyPermissionInfo.java @@ -0,0 +1,57 @@ +package com.didichuxing.doraemonkit.kit.permissionlist; + +public class MyPermissionInfo { + private String name; + private String permissionGroup; + private String description; + private String label; + private String protectionLevel; + + public MyPermissionInfo(String name, String permissionGroup, String description, String protectionLevel) { + this.name = name; + this.permissionGroup = permissionGroup; + this.description = description; + this.protectionLevel = protectionLevel; + label=""; + } + + public void setName(String name) { + this.name = name; + } + + public void setPermissionGroup(String permissionGroup) { + this.permissionGroup = permissionGroup; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setProtectionLevel(String protectionLevel) { + this.protectionLevel = protectionLevel; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + + public String getName() { + return name; + } + + public String getPermissionGroup() { + return permissionGroup; + } + + public String getDescription() { + return description; + } + + public String getProtectionLevel() { + return protectionLevel; + } +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/PermissionListKit.kt b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/PermissionListKit.kt new file mode 100644 index 000000000..d4c6c534e --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/PermissionListKit.kt @@ -0,0 +1,32 @@ +package com.didichuxing.doraemonkit.kit.permissionlist + +import android.app.Activity +import android.content.Context +import com.didichuxing.doraemonkit.R +import com.didichuxing.doraemonkit.kit.AbstractKit +import com.didichuxing.doraemonkit.kit.network.ui.NetWorkMonitorFragment +import com.google.auto.service.AutoService + +/** + * Created by lmh 2022/6/14 + */ +@AutoService(AbstractKit::class) +class PermissionListKit : AbstractKit() { + override val name: Int + get() = R.string.dk_kit_permission_list + override val icon: Int + get() = R.mipmap.dk_permission_list + + override fun onClickWithReturn(activity: Activity): Boolean { + ExpandableActivity.openActivity(activity) + return true + } + + override fun onAppInit(context: Context?) { + } + + override val isInnerKit: Boolean + get() = true + + override fun innerKitId(): String = "dokit_sdk_platform_ck_permission" +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/XMLparser.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/XMLparser.java new file mode 100644 index 000000000..477ddb9b9 --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/XMLparser.java @@ -0,0 +1,55 @@ +package com.didichuxing.doraemonkit.kit.permissionlist; + + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +public class XMLparser { + private HashMap permissonmap; + + public ArrayList parser(InputStream path){ + // 1.权限名-对象的映射map + permissonmap=new HashMap<>(); + //2.创建DocumentBuilderFactory对象 + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + //3.创建DocumentBuilder对象 + try { + ArrayList myPermissionInfoList =new ArrayList<>(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document d = builder.parse(path); + NodeList sList = d.getElementsByTagName("permission"); + //System.out.println(sList.getLength()); + for(int i=0;i getMap(){ + return permissonmap; + } +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/entity/ChildEntity.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/entity/ChildEntity.java new file mode 100644 index 000000000..cf7fd900e --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/entity/ChildEntity.java @@ -0,0 +1,22 @@ +package com.didichuxing.doraemonkit.kit.permissionlist.entity; +import com.didichuxing.doraemonkit.kit.permissionlist.MyPermissionInfo; + +/** + * 子项数据的实体类 + */ +public class ChildEntity { + + private MyPermissionInfo child; + + public ChildEntity(MyPermissionInfo child) { + this.child = child; + } + + public MyPermissionInfo getChild() { + return child; + } + + public void setChild(MyPermissionInfo child) { + this.child = child; + } +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/entity/ExpandableGroupEntity.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/entity/ExpandableGroupEntity.java new file mode 100644 index 000000000..401d409f9 --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/entity/ExpandableGroupEntity.java @@ -0,0 +1,54 @@ +package com.didichuxing.doraemonkit.kit.permissionlist.entity; + +import java.util.ArrayList; + +/** + * 可展开收起的组数据的实体类 它比GroupEntity只是多了一个boolean类型的isExpand,用来表示展开和收起的状态。 + */ +public class ExpandableGroupEntity { + + private String header; + private String footer; + private ArrayList children; + private boolean isExpand; + + public ExpandableGroupEntity(String header, String footer, boolean isExpand, + ArrayList children) { + this.header = header; + this.footer = footer; + this.isExpand = isExpand; + this.children = children; + } + + public String getHeader() { + return header; + } + + public void setHeader(String header) { + this.header = header; + } + + public String getFooter() { + return footer; + } + + public void setFooter(String footer) { + this.footer = footer; + } + + public boolean isExpand() { + return isExpand; + } + + public void setExpand(boolean expand) { + isExpand = expand; + } + + public ArrayList getChildren() { + return children; + } + + public void setChildren(ArrayList children) { + this.children = children; + } +} diff --git a/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/entity/GroupEntity.java b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/entity/GroupEntity.java new file mode 100644 index 000000000..433978a0f --- /dev/null +++ b/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/permissionlist/entity/GroupEntity.java @@ -0,0 +1,43 @@ +package com.didichuxing.doraemonkit.kit.permissionlist.entity; + +import java.util.ArrayList; + +/** + * 组数据的实体类 + */ +public class GroupEntity { + + private String header; + private String footer; + private ArrayList children; + + public GroupEntity(String header, String footer, ArrayList children) { + this.header = header; + this.footer = footer; + this.children = children; + } + + public String getHeader() { + return header; + } + + public void setHeader(String header) { + this.header = header; + } + + public String getFooter() { + return footer; + } + + public void setFooter(String footer) { + this.footer = footer; + } + + public ArrayList getChildren() { + return children; + } + + public void setChildren(ArrayList children) { + this.children = children; + } +} diff --git a/Android/dokit/src/main/res/drawable-v21/holo_gray_dark_ripple_bg.xml b/Android/dokit/src/main/res/drawable-v21/holo_gray_dark_ripple_bg.xml new file mode 100644 index 000000000..545f5f9f6 --- /dev/null +++ b/Android/dokit/src/main/res/drawable-v21/holo_gray_dark_ripple_bg.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/Android/dokit/src/main/res/drawable-v21/holo_red_dark_ripple_bg.xml b/Android/dokit/src/main/res/drawable-v21/holo_red_dark_ripple_bg.xml new file mode 100644 index 000000000..27e4997b7 --- /dev/null +++ b/Android/dokit/src/main/res/drawable-v21/holo_red_dark_ripple_bg.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/Android/dokit/src/main/res/drawable-v21/white_ripple_bg.xml b/Android/dokit/src/main/res/drawable-v21/white_ripple_bg.xml new file mode 100644 index 000000000..79ffedc3e --- /dev/null +++ b/Android/dokit/src/main/res/drawable-v21/white_ripple_bg.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/Android/dokit/src/main/res/drawable-xhdpi/group_adapter_empty_view_image.png b/Android/dokit/src/main/res/drawable-xhdpi/group_adapter_empty_view_image.png new file mode 100644 index 000000000..96a0f83ad Binary files /dev/null and b/Android/dokit/src/main/res/drawable-xhdpi/group_adapter_empty_view_image.png differ diff --git a/Android/dokit/src/main/res/drawable-xhdpi/icon_right.png b/Android/dokit/src/main/res/drawable-xhdpi/icon_right.png new file mode 100644 index 000000000..c0a92baec Binary files /dev/null and b/Android/dokit/src/main/res/drawable-xhdpi/icon_right.png differ diff --git a/Android/dokit/src/main/res/layout/dk_item_log.xml b/Android/dokit/src/main/res/layout/dk_item_log.xml index b42b4c447..355b63fab 100644 --- a/Android/dokit/src/main/res/layout/dk_item_log.xml +++ b/Android/dokit/src/main/res/layout/dk_item_log.xml @@ -11,13 +11,13 @@ android:id="@+id/pid_text" android:layout_width="70dp" android:layout_height="wrap_content" - android:layout_alignParentLeft="true" android:layout_alignParentStart="true" - android:singleLine="true" - android:textColor="@color/dk_color_FFFFFF" + android:layout_alignParentLeft="true" android:paddingEnd="2dp" android:paddingRight="2dp" - android:textSize="12sp"/> + android:singleLine="true" + android:textColor="@color/dk_color_FFFFFF" + android:textSize="12sp" /> + android:singleLine="true" + android:textColor="@color/dk_color_FFFFFF" + android:textSize="12sp" /> + android:singleLine="true" + android:textColor="@color/dk_color_000000" + android:textSize="12sp" /> + android:textSize="12sp" /> + android:singleLine="true" + android:textSize="12sp" /> - \ No newline at end of file + diff --git a/Android/dokit/src/main/res/layout/dk_permission_list_activity_group_list.xml b/Android/dokit/src/main/res/layout/dk_permission_list_activity_group_list.xml new file mode 100644 index 000000000..4df80fc22 --- /dev/null +++ b/Android/dokit/src/main/res/layout/dk_permission_list_activity_group_list.xml @@ -0,0 +1,19 @@ + + + + + + + diff --git a/Android/dokit/src/main/res/layout/dk_permission_list_adapter_child.xml b/Android/dokit/src/main/res/layout/dk_permission_list_adapter_child.xml new file mode 100644 index 000000000..5525f7eee --- /dev/null +++ b/Android/dokit/src/main/res/layout/dk_permission_list_adapter_child.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/Android/dokit/src/main/res/layout/dk_permission_list_adapter_expandable_header.xml b/Android/dokit/src/main/res/layout/dk_permission_list_adapter_expandable_header.xml new file mode 100644 index 000000000..faf2bdae2 --- /dev/null +++ b/Android/dokit/src/main/res/layout/dk_permission_list_adapter_expandable_header.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/Android/dokit/src/main/res/layout/dk_permission_list_group_adapter_default_empty_view.xml b/Android/dokit/src/main/res/layout/dk_permission_list_group_adapter_default_empty_view.xml new file mode 100644 index 000000000..29d7681ad --- /dev/null +++ b/Android/dokit/src/main/res/layout/dk_permission_list_group_adapter_default_empty_view.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/Android/dokit/src/main/res/mipmap-xxhdpi/dk_permission_list.png b/Android/dokit/src/main/res/mipmap-xxhdpi/dk_permission_list.png new file mode 100644 index 000000000..eab44a8ff Binary files /dev/null and b/Android/dokit/src/main/res/mipmap-xxhdpi/dk_permission_list.png differ diff --git a/Android/dokit/src/main/res/values-en-rUS/strings.xml b/Android/dokit/src/main/res/values-en-rUS/strings.xml index 439b954d6..52da9aa2b 100644 --- a/Android/dokit/src/main/res/values-en-rUS/strings.xml +++ b/Android/dokit/src/main/res/values-en-rUS/strings.xml @@ -19,6 +19,7 @@ running service Language + Permission List Tools demo Sandbox diff --git a/Android/dokit/src/main/res/values-zh-rCN/strings.xml b/Android/dokit/src/main/res/values-zh-rCN/strings.xml index 18630b27d..20e3a4204 100644 --- a/Android/dokit/src/main/res/values-zh-rCN/strings.xml +++ b/Android/dokit/src/main/res/values-zh-rCN/strings.xml @@ -26,6 +26,7 @@ 位置模拟 位置微调 位置预设 + 权限列表 实时导航 取色器 对齐标尺 diff --git a/Android/dokit/src/main/res/values-zh-rTW/strings.xml b/Android/dokit/src/main/res/values-zh-rTW/strings.xml index 149b9e5ba..4f20b7c52 100644 --- a/Android/dokit/src/main/res/values-zh-rTW/strings.xml +++ b/Android/dokit/src/main/res/values-zh-rTW/strings.xml @@ -13,6 +13,7 @@ 文件同步助手 Weex + 權限列表 App信息 三方库信息 開發者選項 diff --git a/Android/dokit/src/main/res/values/strings.xml b/Android/dokit/src/main/res/values/strings.xml index 43b6e15de..9301ebd0f 100644 --- a/Android/dokit/src/main/res/values/strings.xml +++ b/Android/dokit/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ - DoKit + DoKit 业务专区 常用工具 LBS @@ -26,6 +26,7 @@ 位置模拟 位置微调 + 权限列表 实时导航 取色器 对齐标尺 @@ -405,4 +406,9 @@ DoKit Web DoKit Studio + + + + + diff --git a/DoraemonKit b/DoraemonKit new file mode 160000 index 000000000..c1531e7cd --- /dev/null +++ b/DoraemonKit @@ -0,0 +1 @@ +Subproject commit c1531e7cdf41e67317095aa7d5f9d4af4afcc203