diff --git a/QtAdb/QtAdb.pro b/QtAdb/QtAdb.pro
index d6109d9..43f09ce 100644
--- a/QtAdb/QtAdb.pro
+++ b/QtAdb/QtAdb.pro
@@ -1,4 +1,5 @@
QT += core gui
+QT += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
@@ -38,6 +39,7 @@ SOURCES += \
textexplainer.cpp \
threads/adbthread.cpp \
threads/thread_createpage.cpp \
+ usb_listener.cpp \
welcomepage.cpp
HEADERS += \
@@ -70,6 +72,7 @@ HEADERS += \
textexplainer.h \
threads/adbthread.h \
threads/thread_createpage.h \
+ usb_listener.h \
welcomepage.h
FORMS += \
diff --git a/QtAdb/about.cpp b/QtAdb/about.cpp
index e83e06c..0fe964d 100644
--- a/QtAdb/about.cpp
+++ b/QtAdb/about.cpp
@@ -5,9 +5,8 @@ about::about(QWidget *parent) :
basePage(parent),
ui(new Ui::about)
{
- ui->setupUi(this);
-
self_castrate();
+ ui->setupUi(this);
QGraphicsDropShadowEffect *shadowEffect_btn_website = new QGraphicsDropShadowEffect(this);
shadowEffect_btn_website->setOffset(0,0);
@@ -58,6 +57,9 @@ about::about(QWidget *parent) :
ui->btn_money->hide();
ui->btn_money_3->hide();
ui->btn_money_4->hide();
+
+ this->setStyleSheet("QToolTip{border:1px solid #BDBDBD; background-color: #ffffff; color:rgba(117, 117, 117, 0.9);font-family: MiSans Medium; font-size:12px;border-radius:4px;}");
+
}
about::~about()
diff --git a/QtAdb/about.ui b/QtAdb/about.ui
index f3159dd..ea86de2 100644
--- a/QtAdb/about.ui
+++ b/QtAdb/about.ui
@@ -112,7 +112,7 @@ QPushButton:pressed{background-color:rgba(255,255,255,0.6);}
- 测试版本:beta-v0.5
+ 测试版本:beta-v0.6
diff --git a/QtAdb/animationwidget.cpp b/QtAdb/animationwidget.cpp
index f1a1f31..1ae0628 100644
--- a/QtAdb/animationwidget.cpp
+++ b/QtAdb/animationwidget.cpp
@@ -15,14 +15,14 @@ void animationWidget::playLoadAnimation()
qDebug() << "wgtHeight = " << wgtHeight;
if(parent->width() <= 600)
{
- animation->setEndValue(QRect(301, 117, 600,wgtHeight));
+ animation->setEndValue(QRect(301, 117 - 6, 600,wgtHeight));
}
else
{
- animation->setEndValue(QRect(301, 117, parent->width(),wgtHeight));
+ animation->setEndValue(QRect(301, 117 - 6, parent->width(),wgtHeight));
}
//animation->setStartValue(QPoint(301 + 50,117));
- animation->setStartValue(QRect(301 + 50, 117, parent->width()-50,wgtHeight));
+ animation->setStartValue(QRect(301 + 50, 117 - 6, parent->width()-50,wgtHeight));
animation->setEasingCurve(QEasingCurve::OutQuart);
@@ -38,14 +38,14 @@ void animationWidget::playLoadAnimation(int h)
//qDebug() << "wgtHeight = " << wgtHeight;
if(parent->width() <= 600)
{
- animation->setEndValue(QRect(301, 117, 600,h));
+ animation->setEndValue(QRect(301, 117 - 6, 600,h));
}
else
{
- animation->setEndValue(QRect(301, 117, parent->width(),h));
+ animation->setEndValue(QRect(301, 117 - 6, parent->width(),h));
}
//animation->setStartValue(QPoint(301 + 50,117));
- animation->setStartValue(QRect(301 + 50, 117, parent->width()-50,h));
+ animation->setStartValue(QRect(301 + 50, 117 - 6, parent->width()-50,h));
animation->setEasingCurve(QEasingCurve::OutQuart);
diff --git a/QtAdb/mainwindow.cpp b/QtAdb/mainwindow.cpp
index 3fd06fa..e3986aa 100644
--- a/QtAdb/mainwindow.cpp
+++ b/QtAdb/mainwindow.cpp
@@ -36,11 +36,22 @@ MainWindow::MainWindow(QWidget *parent)
addIndexItems(); //设置左侧目录
setStyles(); //设置样式
-
/*初始化对象*/
process = new adbProcess();
explainer = new textExplainer();
maker = new pageMaker();
+ listener = new usb_listener();
+
+ //connect(listener, SIGNAL(DevicePlugIn()),this,SLOT(DevicePlugIn()));
+ //connect(listener, SIGNAL(DevicePlugOut()),this,SLOT(DevicePlugOut()));
+ connect(listener, SIGNAL(DeviceChanged()),this,SLOT(refreshDevListLater()));
+ connect(this, SIGNAL(adbDeviceChanged()),this,SLOT(DeviceChanged()));
+ qApp->installNativeEventFilter(listener);
+
+ //listener->EmitMySignal();
+ this->setAttribute(Qt::WA_NativeWindow);
+
+ /*启动监听*/
/*启动ADB,将延长页面创建时间,在此期间显示启动界面,显示了个勾八*/
process->run("adb server");
@@ -75,9 +86,97 @@ void MainWindow::initEnvironmentPATH() //方法:设置环境变
void MainWindow::refreshDevList() //方法:刷新设备列表
{
- ui->comboBox->clear();
+ //ui->comboBox->clear();
+ /*DEBUG*/
+ bool changed = false;
+ qDebug() << "******************一次调用*********************";
+ qDebug() << "refreshDevList devList is empty? " << devList.isEmpty() << QTime::currentTime();
+ qDebug() << "devList.size()" << devList.size();
+
+ for(int i = 0; i < devList.size();i++)
+ {
+ qDebug() << "devList[" << i << "] is :" << devList[i].addr;
+ }
+
+ /*DEBUG_END*/
+ qDebug() << "shit 0";
+ bool devList_is_empty = devList.isEmpty();
+
+ QList tmpList;
+
+ /*给tmpList赋值*/
+ if(!devList_is_empty)
+ {
+ for(int i = 0; i < devList.size();i++)
+ {
+ qDebug() << "shit 3.1";
+ device dev;
+ dev.device_debug = devList[i].device_debug;
+ dev.device_product = devList[i].device_product;
+ dev.addr = devList[i].addr;
+ dev.model = devList[i].model;
+ dev.state = devList[i].state;
+ dev.transport_id = devList[i].transport_id;
+ tmpList.append(dev);
+ }
+ }
+ qDebug() << "tmpList.size()" << tmpList.size();
+
+ //ui->comboBox->clear();
devList.clear(); //清空设备列表
devList = explainer->getDevList_windows(process->run("adb devices -l")); //重新赋值
+ qDebug() << "devList after explain:" << devList.isEmpty();
+
+ /*
+ qDebug() << "shit 1";
+ for(int i = 0; i < tmpList.size();i++)
+ {
+ qDebug() << "shit 2";
+ qDebug() << "tmpList[" << i << "] is :" << devList[i].addr;
+ }
+ for(int i = 0; i < devList.size();i++)
+ {
+ qDebug() << "shit 3";
+ qDebug() << "devList new[" << i << "] is :" << devList[i].addr;
+ }
+ qDebug() << "shit finish";*/
+
+
+ /*判断列表内容是否变化,若变化则发送 adbDeviceChanged 信号*/
+ if(!devList_is_empty)
+ {
+ if(devList.size() == tmpList.size())
+ {
+ for(int i = 0; i < devList.size() && i < tmpList.size() ; i++)
+ {
+ if(devList[i].addr != tmpList[i].addr)
+ {
+ emit adbDeviceChanged();
+ changed = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ emit adbDeviceChanged();
+ changed = true;
+ }
+ }
+ else if(!devList.isEmpty() && tmpList.isEmpty())
+ {
+ emit adbDeviceChanged();
+ changed = true;
+ }
+ else if(devList.isEmpty() && !tmpList.isEmpty())
+ {
+ emit adbDeviceChanged();
+ changed = true;
+ }
+ else
+ {
+ qDebug() << "else:" << devList.isEmpty() << tmpList.isEmpty() << devList_is_empty;
+ }
QList off; //未响应设备索引
@@ -89,6 +188,7 @@ void MainWindow::refreshDevList() //方法:刷新设备列
{
QString devItem = devList[i].state + " " + explainer->get_words_after(devList[i].model, ":") + " " + devList[i].addr;
l.append(devItem);
+ qDebug() << "l[" << i << "] = " << l[i];
if(devList[i].state == "[未响应]")
{
off.append(i);
@@ -99,7 +199,21 @@ void MainWindow::refreshDevList() //方法:刷新设备列
}
}
- ui->comboBox->addItems(l);
+ if(changed)
+ {
+ qDebug() <<"changed so clear";
+ ui->comboBox->clear();
+ ui->comboBox->addItems(l);
+ }
+
+ if(!liangYi)
+ {
+ qDebug() <<"liangYi so clear";
+ ui->comboBox->clear();
+ ui->comboBox->addItems(l);
+ }
+
+ liangYi = false;
for(int i = 0; i < off.count();i++)
{
@@ -115,6 +229,10 @@ void MainWindow::refreshDevList() //方法:刷新设备列
{
current_device = 0;
}
+
+ liangYi = false;
+
+ qDebug() << "******************一次调用结束*********************";
}
void MainWindow::on_refreshButton_clicked() //槽:按下刷新按钮
@@ -130,7 +248,6 @@ void MainWindow::on_refreshButton_clicked() //槽:按下刷新按钮
}*/
initBasePage(6);
- qDebug() <<"8";
}
void MainWindow::setCurrentDevice(int index) //槽:改变所选设备
@@ -540,3 +657,60 @@ void MainWindow::on_cmdBtn_clicked()
batProcess.start(batPath);
batProcess.waitForFinished();
}
+
+void MainWindow::DevicePlugIn()
+{
+ qDebug() << "DevicePlugIn";
+}
+
+void MainWindow::DevicePlugOut()
+{
+ qDebug() << "DevicePlugout";
+}
+
+void MainWindow::DeviceChanged()
+{
+ if(firstBoot == true)
+ {
+ firstBoot = false;
+ }
+ else
+ {
+ QMessageBox::StandardButton result=QMessageBox::warning(NULL, "检测到USB热插拔","您可能插入或拔出了一台ADB设备\n"
+ "将对设备列表进行刷新\n"
+ "(⚠️这会中断当前正在执行的任务)");
+
+ //msgBox->setStyleSheet("background-color:rgba(255,255,255,1);border:0px; border-radius:0px;");
+ //QMessageBox::StandardButton result=QMessageBox::warning(this, "Title","text");
+ //qDebug() << "result =" << result;
+ if(result)
+ {
+ //这里要delete adbprocess
+ on_refreshButton_clicked();
+ }
+ else
+ {
+
+ }
+ //qDebug() << "DeviceChanged";
+ }
+}
+
+void MainWindow::slot_refreshDevList()
+{
+ //qDebug() << "slot_refreshDevList";
+ liangYi = true;
+ refreshDevList();
+}
+
+
+void MainWindow::refreshDevListLater()
+{
+
+ //qDebug() << ">>>>>>>>>>>>>>>>>>>>>>refreshDevListLater";
+ QTimer *timer = new QTimer();
+ connect(timer, SIGNAL(timeout()), this, SLOT(slot_refreshDevList()));
+ timer->setSingleShot(true);
+ timer->start(1000);
+ //timer->deleteLater();
+}
diff --git a/QtAdb/mainwindow.h b/QtAdb/mainwindow.h
index 761dcc0..96fb1bf 100644
--- a/QtAdb/mainwindow.h
+++ b/QtAdb/mainwindow.h
@@ -1,5 +1,9 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
+/*
+#define 布尔 bool
+#define 为 =
+#define 真 true*/
#include
#include
@@ -14,8 +18,8 @@
#include "indexlistitem.h"
#include "basepage.h"
#include "pagemaker.h"
-#include "threads/thread_createpage.h"
#include "about.h"
+#include "usb_listener.h"
#include
#include
@@ -33,6 +37,7 @@ class MainWindow : public QMainWindow
{
Q_OBJECT
signals:
+ void adbDeviceChanged();
public:
MainWindow(QWidget *parent = nullptr);
@@ -49,7 +54,6 @@ class MainWindow : public QMainWindow
QLineEdit * le_port;
QLineEdit * le_code;
-
int current_device;
QList devList;
indexListItem listItems[10];
@@ -81,12 +85,28 @@ private slots:
void addIndexItems();
void setStyles();
- bool taiChi = true;
+ bool taiChi = true; //界面锁定定时器
+ bool liangYi = false; //判断刷新按钮槽函数是被谁调用:false:click()调用 ; true: 自行connect()
+ bool bagua = true; //忘了是干啥的了
+
+ //布尔 太极 为 真;
+
+
+ bool firstBoot = true;
QTimer *taiChiTimer;
+ QTimer *baguaTimer;
basePage * currentPage;
animationWidget * tmpPage;
about * WCMPage2;
+ usb_listener *listener;
+
+public slots:
+ void DevicePlugIn();
+ void DevicePlugOut();
+ void DeviceChanged();
+ void slot_refreshDevList();
+ void refreshDevListLater();
};
#endif // MAINWINDOW_H
diff --git a/QtAdb/sonPages/apps/sp_installer.cpp b/QtAdb/sonPages/apps/sp_installer.cpp
index b6abe55..f29260b 100644
--- a/QtAdb/sonPages/apps/sp_installer.cpp
+++ b/QtAdb/sonPages/apps/sp_installer.cpp
@@ -21,6 +21,7 @@ sp_installer::sp_installer(QWidget *parent) :
QGraphicsDropShadowEffect *shadowEffect_back_to_basePage = new QGraphicsDropShadowEffect(this);
QGraphicsDropShadowEffect *shadowEffect_refreshBtn = new QGraphicsDropShadowEffect(this);
QGraphicsDropShadowEffect *shadowEffect_selectBtn = new QGraphicsDropShadowEffect(this);
+ QGraphicsDropShadowEffect *shadowEffect_tips = new QGraphicsDropShadowEffect(this);
shadowEffect_runBtn->setOffset(0,0);
shadowEffect_runBtn->setColor(Qt::gray);
@@ -42,11 +43,16 @@ sp_installer::sp_installer(QWidget *parent) :
shadowEffect_selectBtn->setColor(Qt::gray);
shadowEffect_selectBtn->setBlurRadius(5);
+ shadowEffect_tips->setOffset(0,0);
+ shadowEffect_tips->setColor(Qt::green);
+ shadowEffect_tips->setBlurRadius(5);
+
ui->back_to_basePage->setGraphicsEffect(shadowEffect_back_to_basePage);
ui->runBtn->setGraphicsEffect(shadowEffect_runBtn);
ui->showOutputBtn->setGraphicsEffect(shadowEffect_showOutputBtn);
ui->refreshBtn->setGraphicsEffect(shadowEffect_refreshBtn);
ui->selectBtn->setGraphicsEffect(shadowEffect_selectBtn);
+ ui->tips->setGraphicsEffect(shadowEffect_tips);
/*
QGraphicsDropShadowEffect *shadowEffect_widget = new QGraphicsDropShadowEffect();
diff --git a/QtAdb/sonPages/apps/sp_installer.ui b/QtAdb/sonPages/apps/sp_installer.ui
index f241e2d..c74e4c6 100644
--- a/QtAdb/sonPages/apps/sp_installer.ui
+++ b/QtAdb/sonPages/apps/sp_installer.ui
@@ -203,6 +203,37 @@ QProgressBar:chunk{
+ -
+
+
+
+ 0
+ 30
+
+
+
+
+ 16777215
+ 30
+
+
+
+
+ MiSans Medium
+ 12
+
+
+
+ background-color:rgba(255,255,255,0.6);border-radius:4px;border:0px;
+
+
+ 执行时切勿插拔设备
+
+
+ Qt::AlignCenter
+
+
+
-
-
diff --git a/QtAdb/sonPages/recovery/sp_recovery.cpp b/QtAdb/sonPages/recovery/sp_recovery.cpp
index 14e6268..13b37fc 100644
--- a/QtAdb/sonPages/recovery/sp_recovery.cpp
+++ b/QtAdb/sonPages/recovery/sp_recovery.cpp
@@ -89,7 +89,7 @@ void sp_recovery::on_runBtn_clicked()
{
//qDebug() << "enter runBtn slot";
ui->progressBar->setVisible(true);
- ui->output->setText("正在刷入,请在设备端查看进度");
+ ui->output->setText("正在刷入,请在设备端查看进度,切勿插拔设备");
QString command;
@@ -110,21 +110,6 @@ void sp_recovery::on_runBtn_clicked()
this->setDisabled(true);
- /*
- pageListItemStruct *productModel = initStruct(devInfo);
- productModel->item->setText_title("设备型号 | DeviceModel");
- productModel->item->setPic(":/ico/image/ico/profile-line.svg");
- productModel->thread->initThread("adb shell getprop ro.product.model", dev);
- QEventLoop::connect(productModel->thread,SIGNAL(signal_output(QString)),productModel->item,SLOT(slot_setText_profile(QString)));
- //QEventLoop::connect(devInfo,SIGNAL(animationEnd()),productModel->item,SLOT(slot_setStyles()));
- productModel->thread->start();
- devInfo->addItemsToList(productModel->item);
- //qDebug() << "item is in thread" << productModel->item->thread();*/
-
- //qDebug() << "command: " << command;
- //qDebug() << "running";
- //process->run_contains_empty(command, dev);
-
zipPath.clear();
labelDisplay.clear();
diff --git a/QtAdb/usb_listener.cpp b/QtAdb/usb_listener.cpp
new file mode 100644
index 0000000..121666b
--- /dev/null
+++ b/QtAdb/usb_listener.cpp
@@ -0,0 +1,91 @@
+#include "usb_listener.h"
+#include
+#include
+
+#include
+
+bool usb_listener::nativeEventFilter(const QByteArray &eventType, void *message, long long *result)
+{
+ MSG* msg = reinterpret_cast(message);
+ //qDebug() << "msg = " << msg;
+ unsigned int msgType = msg->message;
+ //qDebug() << "msgType = " << msgType;
+ //qDebug() << WM_DEVICECHANGE;
+ if(msgType == WM_DEVICECHANGE) {
+ emit DeviceChangeCbk();
+
+ //qDebug() << "msgType = " << msgType;
+ //qDebug() << "WM_DEVICECHANGE = " << WM_DEVICECHANGE;
+ qDebug() << "wParam = " << msg->wParam;
+ //qDebug() << "lParam = " << msg->lParam;
+ //qDebug() << "WM_DEVICECHANGE = " << WM_DEVICECHANGE;
+ qDebug() << "DBT_DEVICEARRIVAL = " << DBT_DEVICEARRIVAL;
+ qDebug() << "DBT_DEVICEREMOVECOMPLETE = " << DBT_DEVICEREMOVECOMPLETE;
+/*
+ PDEV_BROADCAST_HDR lpdb = PDEV_BROADCAST_HDR(msg->lParam);
+ qDebug() << "lpdb = " << msg->lParam;
+ PDEV_BROADCAST_DEVICEINTERFACE pDevInf = PDEV_BROADCAST_DEVICEINTERFACE(lpdb);
+ qDebug() << "pDevInf = " << pDevInf;
+ qDebug() << "pDevInf->dbcc_name = " << pDevInf->dbcc_name;
+ QString device_name = "插入设备(name):"+QString::fromWCharArray(pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8();
+
+ qDebug() << device_name;*/
+ //bool dbg = msg->lParam == WM_DEVICECHANGE;
+ //qDebug() << "msg->lParam == WM_DEVICECHANGE = " <lParam type = " << typeid(msg->lParam).name();
+ //if(msg->wParam == DBT_DEVICEARRIVAL)
+ emit DeviceChanged();
+ //if(msg->lParam == WM_DEVICECHANGE)
+ if(msg->wParam == DBT_DEVICEARRIVAL)
+ {
+ qDebug("usb in");
+ emit DevicePlugIn(); //触发信号
+ }
+ if(msg->wParam == DBT_DEVICEREMOVECOMPLETE)
+ {
+ qDebug("usb out");
+ emit DevicePlugOut(); //触发信号
+ }
+ }
+
+ return QWidget::nativeEvent(eventType, message, result);
+}
+
+void usb_listener::EmitMySignal()
+{
+ emit DevicePlugIn();
+}
+/*
+bool usb_listener::nativeEvent(const QByteArray &eventType, void *message, long long *result)
+{
+ MSG* msg = reinterpret_cast(message);//第一层解算
+ qDebug() << "msg = " << msg;
+ UINT msgType = msg->message;
+ if(msgType==WM_DEVICECHANGE)
+ {
+ PDEV_BROADCAST_HDR lpdb = PDEV_BROADCAST_HDR(msg->lParam);//第二层解算
+ switch (msg->wParam) {
+ case DBT_DEVICEARRIVAL:
+ if(lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
+ {
+ PDEV_BROADCAST_DEVICEINTERFACE pDevInf = PDEV_BROADCAST_DEVICEINTERFACE(lpdb);
+ QString device_name = "插入设备(name):"+QString::fromWCharArray(pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8();
+
+ qDebug()<< device_name;
+ }
+ break;
+ case DBT_DEVICEREMOVECOMPLETE:
+ if(lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
+ {
+ PDEV_BROADCAST_DEVICEINTERFACE pDevInf = PDEV_BROADCAST_DEVICEINTERFACE(lpdb);
+ QString device_name = "移除设备(name):"+QString::fromWCharArray(pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8();
+
+ qDebug()<< device_name;
+ }
+ break;
+ }
+ }
+ return false;
+}
+*/
diff --git a/QtAdb/usb_listener.h b/QtAdb/usb_listener.h
new file mode 100644
index 0000000..7b287a9
--- /dev/null
+++ b/QtAdb/usb_listener.h
@@ -0,0 +1,27 @@
+#ifndef USB_LISTENER_H
+#define USB_LISTENER_H
+
+#include
+#include
+#include
+#include
+
+class usb_listener:public QWidget, public QAbstractNativeEventFilter
+{
+ Q_OBJECT
+public:
+
+ void EmitMySignal();
+
+protected:
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long long *result);
+ //bool nativeEvent(const QByteArray &eventType, void *message, long long *result);
+
+signals:
+ void DeviceChangeCbk();
+ void DeviceChanged();
+ void DevicePlugIn();
+ void DevicePlugOut();
+};
+
+#endif // USB_LISTENER_H
diff --git a/README.md b/README.md
index 2566a25..778a09d 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,9 @@
QtAdb 是一个基于 [Qt](https://www.qt.io/) 的 Android 工具集合。
-> QtAdb 仍处于开发中,暂未正式发布,但您仍可以下载体验版本。
+> ~~QtAdb 仍处于开发中,暂未正式发布,但您仍可以下载体验版本。~~
+>
+> QtAdb 已于 2022/8/17 发布第一个正式可用的版本 beta-v0.6 ,将进入功能添加与细节优化阶段。
## 🧑💻开发目的
@@ -24,7 +26,7 @@ Android 系统的可玩性在 adb 的加成下变得更加的丰富,由此涌
- ~~不仅支持 adb 命令,还集成了一定数量的 **Fastboot** 命令,方便刷机等操作。~~*暂未实现*
- 提供命令模板,使用者可直接复制命令并自行执行。
-- 支持多种状态显示及使用:开机、Recovery、Fastboot 及 adb sideload.
+- 支持多种状态显示及使用:开机、Recovery、~~Fastboot~~及 adb sideload.
## 🛠️功能
@@ -89,9 +91,10 @@ Android 系统的可玩性在 adb 的加成下变得更加的丰富,由此涌
- 跨平台
- 完善网站
- 文件管理(~~都连上电脑了,为什么不直接用电脑的文件管理~~)
-- 设备插拔检测
+- ~~设备插拔检测~~
- 集成scrcpy
-- 视觉反馈
+- ~~视觉反馈~~
+
- ~~页面切换加载进度条~~
- ~~页面切换动画效果~~
- ~~安装应用进度条~~