<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
+ <component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+ implementation files('libs/ICLoger-release.aar')
}
\ No newline at end of file
<application
android:allowBackup="true"
+ android:name=".App"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
package com.ic.launcher.loop;
-public class App {
+import android.app.Application;
+
+import com.ic.iclooger.ICLogger;
+
+public class App extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ ICLogger.init(getApplicationContext(), "LOOP-PAGE-LAUNCHER");
+ }
}
package com.ic.launcher.loop;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.viewpager2.widget.ViewPager2;
-
import android.os.Bundle;
import android.view.View;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.viewpager2.widget.ViewPager2;
+
import com.ic.launcher.loop.adapter.MainPageAdapter;
import com.ic.launcher.loop.presenter.MainPagePresenter;
+import com.ic.launcher.loop.view.SimpleStatusBarView;
+import com.ic.launcher.loop.view.StatusBarView;
public class LauncherActivity extends AppCompatActivity {
private MainPageAdapter mainPageAdapter;
private MainPagePresenter mainPagePresenter;
+ private ViewPager2 looperPage;
+ private StatusBarView statusBar;
+ private SimpleStatusBarView simpleStatusBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
initPresenter();
}
+ @Override
+ public void onBackPressed() {
+ //TODO:
+ }
+
private void initPresenter() {
mainPagePresenter = MainPagePresenter.getInstance(this);
mainPagePresenter.appListValues.observe(this, newList -> {
mainPageAdapter.updateAppList(newList);
+ //数据设置的时候,把页面移动到中间
+ //实现伪无限滑动
+ looperPage.setCurrentItem(mainPageAdapter.getItemCount() / 2,
+ false);
});
}
//处理点击事件
mainPageAdapter.setOnItemClickListener(item -> {
//打开应用
- //TODO:
+
});
+ looperPage.registerOnPageChangeCallback(onPageChangeCallback);
}
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ looperPage.unregisterOnPageChangeCallback(onPageChangeCallback);
+ }
+
+ private final ViewPager2.OnPageChangeCallback onPageChangeCallback = new ViewPager2.OnPageChangeCallback() {
+ @Override
+ public void onPageSelected(int position) {
+ boolean isMainPage = mainPageAdapter.getItemViewType(position) == MainPageAdapter.TYPE_MAIN;
+ statusBar.setVisibility(isMainPage ? View.VISIBLE : View.GONE);
+ simpleStatusBar.setVisibility(isMainPage ? View.GONE : View.VISIBLE);
+ }
+ };
+
private void initView() {
- ViewPager2 looperPage = findViewById(R.id.main_looper_pager);
+ looperPage = findViewById(R.id.main_looper_pager);
mainPageAdapter = new MainPageAdapter();
looperPage.setAdapter(mainPageAdapter);
+ statusBar = findViewById(R.id.status_bar);
+ statusBar.initPresenter(this);
+ simpleStatusBar = findViewById(R.id.simple_status_bar);
}
}
\ No newline at end of file
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
@Override
public int getItemViewType(int position) {
+ int targetIndex = position % totalSize;
//第一个为Launcher的主界面
- if (position == 0) {
+ if (targetIndex == 0) {
return TYPE_MAIN;
//后面的为其他内容
} else {
@Override
public void onBindViewHolder(@NonNull InnerHolder holder, int position) {
+ int targetIndex = position % totalSize;
//绑定数据
int itemViewType = getItemViewType(position);
if (itemViewType != TYPE_MAIN) {
- int targetPosition = position - 1;
+ int targetPosition = targetIndex - 1;
AppItem appItem = appItemList.get(targetPosition);
View itemView = holder.itemView;
TextView itemTitle = itemView.findViewById(R.id.app_title_tv);
itemTitle.setText(appItem.getTitleResId());
-
+ ImageView iconView = itemView.findViewById(R.id.app_icon_iv);
+ iconView.setImageResource(appItem.getIconResId());
}
}
public int getItemCount() {
totalSize = appItemList.size() + 1;
//加上一个首页
- //TODO:后面要做无限循环
- return totalSize;
+ //伪无限循环
+ return totalSize * 1000;
}
public void setOnItemClickListener(OnItemClickListener listener) {
// -体温
appItems.add(new AppItem(
R.string.app_title_temperature,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_temperature,
R.string.app_package_name_temperature,
true
));
// -健康
appItems.add(new AppItem(
R.string.app_title_health,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_health,
R.string.app_package_name_health,
true
));
// -运动
appItems.add(new AppItem(
R.string.app_title_sport,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_sport,
R.string.app_package_name_sport,
true
));
// -天气
appItems.add(new AppItem(
R.string.app_title_weather,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_weather,
R.string.app_package_name_weather,
true
));
// -电话
appItems.add(new AppItem(
R.string.app_title_phone,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_phone,
R.string.app_package_name_phone,
true
));
// -微聊
appItems.add(new AppItem(
R.string.app_title_ic_talk,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_ic_talk,
R.string.app_package_name_ic_talk,
true
));
// -联系人
appItems.add(new AppItem(
R.string.app_title_contact,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_contact,
R.string.app_package_name_contact,
true
));
// -拍照
appItems.add(new AppItem(
R.string.app_title_camera,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_phone,
R.string.app_package_name_photo,
true
));
// -相册
appItems.add(new AppItem(
R.string.app_title_photo,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_photo,
R.string.app_package_name_phone,
true
));
// -短信
appItems.add(new AppItem(
R.string.app_title_sms,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_sms,
R.string.app_package_name_sms,
true
));
// -记录
appItems.add(new AppItem(
R.string.app_title_record,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_record,
R.string.app_package_name_record,
true
));
// -签到
appItems.add(new AppItem(
R.string.app_title_sign,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_sign,
R.string.app_package_name_sign,
true
));
// -设定
appItems.add(new AppItem(
R.string.app_title_settings,
- R.mipmap.ic_launcher,
+ R.mipmap.app_icon_settings,
R.string.app_package_name_settings,
true
));
package com.ic.launcher.loop.presenter;
+import android.content.BroadcastReceiver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.net.wifi.WifiManager;
+
import androidx.lifecycle.MutableLiveData;
+import com.ic.iclooger.ICLogger;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static com.ic.launcher.loop.utils.Constants.SETTINGS;
+
public class StatusBarPresenter extends StatusBarBasePresenter {
+ private final Context mContext;
//网络状态
public MutableLiveData<Boolean> isWifiOpen = new MutableLiveData<>();
//GPS状态
//开启闹钟提示
public MutableLiveData<Boolean> alarmState = new MutableLiveData<>();
//未读短信提示
- public MutableLiveData<Boolean> msgReadState = new MutableLiveData<>();
+ public MutableLiveData<Boolean> msgUnReadState = new MutableLiveData<>();
//未接电话提示
public MutableLiveData<Boolean> missCallState = new MutableLiveData<>();
//静音模式
public MutableLiveData<Boolean> silentState = new MutableLiveData<>();
//微聊新消息
public MutableLiveData<Boolean> icTalkMsgState = new MutableLiveData<>();
+ //
+ private final ExecutorService executorService;
+ //
+ private NetworkConnectChangedReceiver mNetworkChangeListener;
+
+ private StatusBarPresenter(Context context) {
+ this.mContext = context;
+ executorService = Executors.newSingleThreadExecutor();
+ //监听各种状态
+ //需要初始化一次,然后进行监听
+ getWifiState();
+ getGpsState();
+ getBtState();
+ getWearState();
+ getUnReadMsgState();
+ getAlarmState();
+ getWarningMsgReadState();
+ getSilentState();
+ checkIcTalkMsg();
+ checkHasMissCall();
+ }
+
+ private void checkHasMissCall() {
+ //TODO:
+ missCallState.postValue(true);
+ }
+
+ private void getSilentState() {
+ //TODO:
+ silentState.postValue(true);
+ }
+
+ private void checkIcTalkMsg() {
+ icTalkMsgState.postValue(true);
+ }
+
+ private void getWarningMsgReadState() {
+ warningReadState.postValue(true);
+ }
+
+ private void getAlarmState() {
+ alarmState.postValue(true);
+ }
+
+ private void getUnReadMsgState() {
+ msgUnReadState.postValue(true);
+ }
+
+ private void getWearState() {
+ wearState.postValue(true);
+ }
+
+ private void getBtState() {
+ btState.postValue(true);
+ }
+
+ private void getGpsState() {
+ gpsState.postValue(true);
+ }
+
+ private void getWifiState() {
+ //把它写到库里吧
+ executorService.submit(() -> {
+ WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ boolean state = wifiManager.isWifiEnabled();
+ ContentValues contentValues = new ContentValues();
+ contentValues.put("s_key", "wifi_state");
+ contentValues.put("s_value", state ? "1" : "0");
+ isWifiOpen.postValue(state);
+ mContext.getContentResolver().insert(Uri.parse(SETTINGS),
+ contentValues);
+ });
+ //也监听广播吧,否则更新不了UI
+ IntentFilter filter = new IntentFilter();
+ filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
+ filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ mNetworkChangeListener = new NetworkConnectChangedReceiver();
+ }
+
+
+ class NetworkConnectChangedReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 这个监听wifi的打开与关闭,与wifi的连接无关
+ if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
+ int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
+ ICLogger.d("wifiState == > " + wifiState);
+ switch (wifiState) {
+ case WifiManager.WIFI_STATE_DISABLED:
+ case WifiManager.WIFI_STATE_DISABLING:
+ isWifiOpen.postValue(false);
+ break;
+ case WifiManager.WIFI_STATE_ENABLING:
+ case WifiManager.WIFI_STATE_ENABLED:
+ isWifiOpen.postValue(true);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ private static StatusBarPresenter sInstance = null;
+ public static StatusBarPresenter getInstance(Context context) {
+ if (sInstance == null) {
+ sInstance = new StatusBarPresenter(context);
+ }
+ return sInstance;
+ }
}
--- /dev/null
+package com.ic.launcher.loop.utils;
+
+public class Constants {
+ public static final String PATH = "settings";
+ public static final String AUTHORITY = "com.ic.fzd.settings";
+ public static final String SETTINGS = "content://" + AUTHORITY + "/" + PATH;
+ public static final String LAUNCHER_APP_LIST_STYLE = "launcher_app_list_style";
+ public static final String BRIGHTNESS_VALUE = "brightness_value";
+}
-package com.ic.launcher.view;
+package com.ic.launcher.loop.view;
import android.content.Context;
import android.graphics.Bitmap;
import androidx.annotation.Nullable;
-import com.ic.launcher.R;
-import com.ic.launcher.util.ICLogger;
+import com.ic.iclooger.ICLogger;
+import com.ic.launcher.loop.R;
+
public class BatteryView extends View {
-package com.ic.launcher.view;
+package com.ic.launcher.loop.view;
import android.content.Context;
import android.graphics.Bitmap;
import androidx.annotation.Nullable;
-import com.ic.launcher.R;
-import com.ic.launcher.util.ICLogger;
+import com.ic.iclooger.ICLogger;
+import com.ic.launcher.loop.R;
public class SignalView extends View {
import android.content.Context;
import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.ic.launcher.loop.R;
+
public class SimpleStatusBarView extends FrameLayout {
+ private SignalView signalView;
+
public SimpleStatusBarView(@NonNull Context context) {
- super(context);
+ this(context, null);
}
public SimpleStatusBarView(@NonNull Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
+ this(context, attrs, 0);
}
public SimpleStatusBarView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ LayoutInflater.from(context).inflate(
+ R.layout.item_simple_status_bar, this
+ );
+ signalView = findViewById(R.id.signal_view);
+ signalView.noNetwork();
}
}
import android.content.Context;
import android.util.AttributeSet;
+import android.view.LayoutInflater;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.lifecycle.LifecycleOwner;
+
+import com.ic.launcher.loop.R;
+import com.ic.launcher.loop.presenter.StatusBarPresenter;
+
+public class StatusBarView extends FrameLayout {
+
+ private StatusBarPresenter statusBarPresenter;
-public class StatusBarView extends FrameLayout {
public StatusBarView(@NonNull Context context) {
- super(context);
+ this(context, null);
}
public StatusBarView(@NonNull Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
+ this(context, attrs, 0);
}
public StatusBarView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ //加载布局
+ LayoutInflater.from(context).inflate(R.layout.item_status_bar, this);
+ }
+
+ public void initPresenter(LifecycleOwner lifecycleOwner) {
+ statusBarPresenter = StatusBarPresenter.getInstance(getContext());
+ statusBarPresenter.alarmState.observe(lifecycleOwner, isAlarmOpen -> {
+ //设置闹钟图标显示还是隐藏
+ //TODO:
+ });
+ statusBarPresenter.btState.observe(lifecycleOwner, isOpen -> {
+ //TODO:蓝牙是否显示
+ });
+ statusBarPresenter.gpsState.observe(lifecycleOwner, isOpen -> {
+ //GPS定位是否打开
+ });
+ statusBarPresenter.icTalkMsgState.observe(lifecycleOwner, hasIcTalkMsg -> {
+ //是否有微聊消息
+ });
+ statusBarPresenter.isWifiOpen.observe(lifecycleOwner, isWifiOpen -> {
+ //wifi是否打开
+ });
+ statusBarPresenter.missCallState.observe(lifecycleOwner, hasMiss -> {
+ //是否有未接电话
+ });
+ statusBarPresenter.wearState.observe(lifecycleOwner, hasWear -> {
+ //是否有穿戴
+ });
+ statusBarPresenter.msgUnReadState.observe(lifecycleOwner, hasRead -> {
+ //消息是否有读
+ });
+ statusBarPresenter.warningReadState.observe(lifecycleOwner, hasRead -> {
+ //警告消息是否有读
+ });
+ statusBarPresenter.silentState.observe(lifecycleOwner, isSilent -> {
+ //是不是静音状态
+ });
+ statusBarPresenter.batteryLev.observe(lifecycleOwner, lev -> {
+ //电量还有多少
+ });
+ statusBarPresenter.signalLev.observe(lifecycleOwner, lev -> {
+ //信号强度
+ });
+ statusBarPresenter.isCharging.observe(lifecycleOwner, isCharging -> {
+ //是否在充电
+ });
}
}
<!--在首页时显示:顶部的状态栏-->
<com.ic.launcher.loop.view.StatusBarView
+ android:id="@+id/status_bar"
android:layout_width="match_parent"
- android:layout_height="42dp"
- android:visibility="gone"
+ android:layout_height="34dp"
android:background="#00ffaa"
+ android:visibility="gone"
app:layout_constraintTop_toTopOf="parent" />
<!--在应用列表时显示:顶部的时间栏-->
<com.ic.launcher.loop.view.SimpleStatusBarView
+ android:id="@+id/simple_status_bar"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="#98aaff"
+ android:layout_height="34dp"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent" />
android:id="@+id/app_icon_iv"
android:layout_width="180dp"
android:layout_height="180dp"
- android:background="#09aaf8"
+ android:src="@mipmap/app_icon_contact"
app:layout_constraintBottom_toTopOf="@id/app_title_tv"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:id="@+id/app_title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
+ android:layout_marginTop="10dp"
android:lines="1"
android:text="app名称"
android:textColor="@color/white"
<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
android:layout_height="match_parent">
+
+ <com.ic.launcher.loop.view.SignalView
+ android:layout_width="wrap_content"
+ android:id="@+id/signal_view"
+ android:layout_height="wrap_content"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintLeft_toLeftOf="parent" />
+
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="12:12"
+ android:textColor="@color/white"
+ android:textSize="22sp"
+ android:textStyle="bold"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintRight_toRightOf="parent" />
+
+
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
app:layout_constraintLeft_toLeftOf="parent" />
+
+
+
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"