Android总结
Android总结
原文的作者写的很好,推荐前往阅读,本片记录纯粹是为了方便自己之后复习的时候使用观看
一、修改阿里云仓库
外层build.gradle
buildscript {
repositories {
google()
mavenCentral()
maven {url 'https://developer.huawei.com/repo/'}
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.4"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
二、Android引用XUI
1.官网地址
https://github.com/xuexiangjys/XUI/wiki
2. 整合方法
2.1 根目录settings.gradle的dependencyResolutionManagement
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url "https://jitpack.io" }
}
}
2.2 androidx项目中添加依赖
implementation 'com.github.xuexiangjys:XUI:1.1.9'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'com.github.bumptech.glide:glide:4.12.0'
2.3 修改values中的themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.IT_Application" parent="XUITheme.Phone">//将此处修改为所需的类型
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
2.4 创建MyApplication类
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
XUI.init(this); //初始化UI框架
XUI.debug(true); //开启UI框架调试日志
}
}
2.5 AndroidManifest.xml中注册
<application
android:name=".MyApplication" //添加到此处
android:allowBackup="true"
android:icon="@mipmap/logo"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.IT_Application">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
三、自定义可左右及上下滑动的表格
1. 自定义SyncHorizontalScrollView
public class SyncHorizontalScrollView extends HorizontalScrollView {
private View mView;
public SyncHorizontalScrollView(Context context) {
super(context);
}
public SyncHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SyncHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mView != null) {
mView.scrollTo(l, t);
}
}
public void setScrollView(View view) {
mView = view;
}
}
2. 自定义NoscrollListView
public class NoscrollListView extends ListView {
public NoscrollListView(Context context) {
super(context);
}
public NoscrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NoscrollListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
3. 页面Activity
public class ListActivity extends AppCompatActivity {
private NoscrollListView mLeft;
private LeftAdapter mLeftAdapter;
private NoscrollListView mData;
private DataAdapter mDataAdapter;
private SyncHorizontalScrollView mHeaderHorizontal;
private SyncHorizontalScrollView mDataHorizontal;
private List<Label> mListData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
TitleBar mTitleBar= findViewById(R.id.listTitle);
//监听返回按键
mTitleBar.setLeftClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
if (mListData!=null){
mListData.clear();
}
}
});
initView();
}
private void initView(){
mLeft = (NoscrollListView) findViewById(R.id.lv_left);
mData = (NoscrollListView) findViewById(R.id.lv_data);
mDataHorizontal = (SyncHorizontalScrollView) findViewById(R.id.data_horizontal);
mHeaderHorizontal = (SyncHorizontalScrollView) findViewById(R.id.header_horizontal);
mDataHorizontal.setScrollView(mHeaderHorizontal);
mHeaderHorizontal.setScrollView(mDataHorizontal);
//获取数据
LabelService LabelService = new LabelService();
mListData = LabelService.queryAll();
mLeftAdapter= new LeftAdapter();
mLeft.setAdapter(mLeftAdapter);
mDataAdapter = new DataAdapter();
mData.setAdapter(mDataAdapter);
}
class LeftAdapter extends BaseAdapter {
@Override
public int getCount() {
if (mListData!=null){
return mListData.size();
}
return 0;
}
@Override
public Object getItem(int position) {
return mListData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(ListActivity.this).inflate(R.layout.item_left, null);
holder.tvLeft = (TextView) convertView.findViewById(R.id.tv_left);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvLeft.setText("第" + (position+1)+ "行");
return convertView;
}
class ViewHolder {
TextView tvLeft;
}
}
class DataAdapter extends BaseAdapter {
@Override
public int getCount() {
if (mListData!=null){
return mListData.size();
}
return 0;
}
@Override
public Object getItem(int position) {
return mListData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
holder = new ViewHolder();
convertView = LayoutInflater.from(ListActivity.this).inflate(R.layout.item_data, null);
holder.equipment = convertView.findViewById(R.id.tv_data_equipmentName);
holder.equipment.setText(mListData.get(position).getEquipment());
holder.dept = convertView.findViewById(R.id.tv_data_dept);
holder.dept.setText(mListData.get(position).getDept());
holder.person = convertView.findViewById(R.id.tv_data_person);
holder.person.setText(mListData.get(position).getPerson());
holder.assetNumber = convertView.findViewById(R.id.tv_data_assetNumber);
holder.assetNumber.setText(mListData.get(position).getAssetNumber());
holder.assetModel = convertView.findViewById(R.id.tv_data_assetModel);
holder.assetModel.setText(mListData.get(position).getAssetModel());
holder.secretLevel = convertView.findViewById(R.id.tv_data_secretLevel);
holder.secretLevel.setText(mListData.get(position).getSecretLevel());
holder.purpose = convertView.findViewById(R.id.tv_data_purpose);
holder.purpose.setText(mListData.get(position).getPurpose());
holder.mac = convertView.findViewById(R.id.tv_data_mac);
holder.mac.setText(mListData.get(position).getMac());
holder.s_n = convertView.findViewById(R.id.tv_data_s_n);
holder.s_n.setText(mListData.get(position).getS_n());
holder.phone = convertView.findViewById(R.id.tv_data_phone);
holder.phone.setText(mListData.get(position).getPhone());
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
class ViewHolder {
TextView equipment;
TextView dept;
TextView person;
TextView assetNumber;
TextView assetModel;
TextView purpose;
TextView secretLevel;
TextView mac;
TextView s_n;
TextView phone;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
4. activity.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/blue_start"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:orientation="vertical"></LinearLayout>
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<LinearLayout
android:id="@+id/lin_header_content"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="3"
android:background="@color/blue_start"
android:orientation="vertical">
<com.example.it_application.SyncHorizontalScrollView
android:id="@+id/header_horizontal"
android:layout_width="match_parent"
android:layout_height="50dp"
android:overScrollMode="never"
android:scrollbars="none">
<LinearLayout
android:id="@+id/lin_year_title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/equipmentName"/>
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/dept"/>
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/person"/>
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/assetNumber"/>
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/assetModel"/>
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/secretLevel"/>
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/purpose"/>
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/mac"/>
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/s_n"/>
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/phone"/>
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
</LinearLayout>
</com.example.it_application.SyncHorizontalScrollView>
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#cccccc"/>
<ScrollView
android:id="@+id/scroll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:orientation="horizontal">
<com.example.it_application.NoscrollListView
android:id="@+id/lv_left"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:overScrollMode="never"
android:scrollbars="none"/>
<View
android:layout_width="1px"
android:layout_height="match_parent"
android:background="#cccccc"/>
<LinearLayout
android:id="@+id/lin_data_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:orientation="vertical">
<com.example.it_application.SyncHorizontalScrollView
android:id="@+id/data_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:scrollbars="none">
<com.example.it_application.NoscrollListView
android:id="@+id/lv_data"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:scrollbars="none"/>
</com.example.it_application.SyncHorizontalScrollView>
</LinearLayout>
</LinearLayout>
</ScrollView>
5. 左侧行数列item_left.xml
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:background="@color/blue_start"
android:text="第1行"/>
</LinearLayout>
</LinearLayout>
6. 内容item_data.xml
<?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">
<LinearLayout
android:id="@+id/lin_content"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_data_equipmentName"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center" />
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:id="@+id/tv_data_dept"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center" />
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:id="@+id/tv_data_person"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center" />
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:id="@+id/tv_data_assetNumber"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center" />
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:id="@+id/tv_data_assetModel"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center" />
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:id="@+id/tv_data_secretLevel"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center" />
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:id="@+id/tv_data_purpose"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center" />
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:id="@+id/tv_data_mac"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center" />
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:id="@+id/tv_data_s_n"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center" />
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
<TextView
android:id="@+id/tv_data_phone"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center" />
<View
android:layout_width="1px"
android:layout_height="50dp"
android:background="#cccccc"/>
</LinearLayout>
</LinearLayout>
此方法借鉴于:https://www.cnblogs.com/begin1949/p/5910785.html
四、子线程中更新UI的方法
Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//执行调用主线程中的方法
}
};
//开启线程启动导入文件
Thread importThread = new Thread() {
@Override
public void run() {
super.run();
inventoryService.importInventoryFile(inventoryDao, filePath);
Message message = new Message();
handler.sendMessage(message);
}
};
importThread.start();
此方法借鉴于 https://www.jianshu.com/p/ce34731f802e
五、调用文件管理器进行选择文件
1、全局对象
//全局intentActivityResultLauncher对象
private ActivityResultLauncher<Intent> intentActivityResultLauncher;
2、开启文件选择器
//点击导入按钮
Uri uri = Uri.parse("content://com.android.externalstorage.documents/document/primary:Download");
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
//限制文件类型
intent.setType("text/plain");
intent.addCategory(Intent.CATEGORY_OPENABLE);
//限制打开文件夹的路径
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri);
intentActivityResultLauncher.launch(intent);
3、接收返回的URI
/**
* 注册registerForActivityResult
* 选择文件后解析的方法
*/
public void myRegisterForActivityResult() {
intentActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
Intent intent = result.getData();
Uri uri = intent.getData();
//转换的工具类
String filePath = UriUtil.getPath(getContext(), uri);
});
}
4、uri转换FilePath工具类
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import androidx.annotation.RequiresApi;
/**
* @description Url工具类
* @version 1.0.0
*/
public class UriUtil {
/**
* 从Uri获取文件路径,存储路径需要获取
* android.permission.READ_EXTERNAL_STORAGE权限
* 适用于MediaStore和其他基于文件的内容提供
*
* @param context 上下文对象
* @param uri Uri
*/
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static String getPath(Context context, Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix