卡片效果

This commit is contained in:
zhangyuanzhen
2020-03-12 16:44:22 +08:00
parent 1827af85c6
commit 90f1c5b13f
27 changed files with 279 additions and 93 deletions

View File

@@ -21,8 +21,6 @@ buildscript {
classpath 'com.android.tools.build:gradle:3.5.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.alibaba:arouter-register:1.0.2"
classpath 'com.novoda:bintray-release:0.8.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}

View File

@@ -89,8 +89,7 @@ ext {
modulecommon : "com.mogo.module:module-common:${MOGO_MODULE_COMMON_VERSION}",
modulemain : "com.mogo.module:module-main:${MOGO_MODULE_MAIN_VERSION}",
modulemap : "com.mogo.module:module-map:${MOGO_MODULE_MAP_VERSION}",
moduleservice : "com.mogo.module:module-service:${CARD_LIBRARY_VERSION}",
uicard : "com.mogo.ui:card-libaray:${MOGO_MODULE_SERVICE_VERSION}",
moduleservice : "com.mogo.module:module-service:${MOGO_MODULE_SERVICE_VERSION}",
mogoservice : "com.mogo.service:mogo-service:${MOGO_SERVICE_VERSION}",
mogoserviceapi : "com.mogo.service:mogo-service-api:${MOGO_SERVICE_API_VERSION}",
moduleapps : "com.mogo.module:module-apps:${MOGO_MODULE_APPS_VERSION}",

View File

@@ -1 +0,0 @@
/build

View File

@@ -1,36 +0,0 @@
apply plugin: 'com.android.library'
apply plugin: 'com.novoda.bintray-release'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
defaultConfig {
targetSdkVersion rootProject.ext.android.targetSdkVersion
minSdkVersion rootProject.ext.android.minSdkVersion
versionCode Integer.valueOf(VERSION_CODE)
versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION")
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
}
dependencies {
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.androidxrecyclerview
testImplementation 'org.robolectric:robolectric:3.0'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.13.0'
testImplementation 'org.hamcrest:hamcrest-library:1.3'
androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()
//publish {
// artifactId = 'discrete-scrollview'
// userOrg = rootProject.userOrg
// groupId = rootProject.groupId
// uploadName = rootProject.uploadName
// publishVersion = rootProject.publishVersion
// description = rootProject.description
// licences = rootProject.licences
//}

View File

@@ -1,3 +0,0 @@
GROUP=com.mogo.ui
POM_ARTIFACT_ID=card-libaray
VERSION_CODE=1

View File

@@ -1,17 +0,0 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\yarolegovich\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@@ -1 +0,0 @@
<manifest package="com.yarolegovich.discretescrollview" />

View File

@@ -1,4 +0,0 @@
<resources>
<string name="dsv_ex_msg_dont_set_lm">You should not set LayoutManager on DiscreteScrollView.class instance. Library uses a special one. Just don\'t call the method.</string>
<string name="dsv_ex_msg_adapter_wrong_recycler">InfiniteScrollAdapter is supposed to work only with DiscreteScrollView</string>
</resources>

View File

@@ -46,7 +46,6 @@ dependencies {
if (Boolean.valueOf(RELEASE)) {
implementation rootProject.ext.dependencies.mogomap
implementation rootProject.ext.dependencies.mogomapapi
implementation rootProject.ext.dependencies.mogomapapi
implementation rootProject.ext.dependencies.mogoutils
api rootProject.ext.dependencies.mogocommons
api rootProject.ext.dependencies.mogoserviceapi
@@ -58,7 +57,6 @@ dependencies {
api project(":foudations:mogo-commons")
api project(':services:mogo-service-api')
implementation project(':modules:mogo-module-common')
implementation project(":libraries:card-library")
}
}

View File

@@ -3,29 +3,25 @@ package com.mogo.module.apps;
import android.os.Bundle;
import android.view.View;
import android.widget.HorizontalScrollView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSnapHelper;
import androidx.recyclerview.widget.RecyclerView;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.commons.mvp.MvpFragment;
import com.mogo.module.apps.adapter.AppIndicatorAdapter;
import com.mogo.module.apps.utils.CardScaleTransformer;
import com.mogo.module.apps.utils.LaunchUtils;
import com.mogo.module.common.MogoModulePaths;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.analytics.IMogoAnalytics;
import com.mogo.service.cardmanager.IMogoCardChangedListener;
import com.mogo.service.fragmentmanager.FragmentDescriptor;
import com.mogo.service.fragmentmanager.IMogoFragmentManager;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.utils.TipToast;
import com.mogo.utils.logger.Logger;
import com.yarolegovich.discretescrollview.DiscreteScrollView;
import com.yarolegovich.discretescrollview.transform.ScaleTransformer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@@ -38,8 +34,10 @@ import java.util.Map;
*/
public class AppNavigatorFragment extends MvpFragment<AppNavigatorView, AppNavigatorPresenter>
implements AppNavigatorView, DiscreteScrollView.OnItemChangedListener<RecyclerView.ViewHolder>,
DiscreteScrollView.ScrollStateChangeListener<RecyclerView.ViewHolder> {
DiscreteScrollView.ScrollStateChangeListener<RecyclerView.ViewHolder>,
IMogoCardChangedListener {
private static final String TAG = "AppNavigatorFragment";
private View mApps;
private IMogoFragmentManager mMogoFragmentManager;
@@ -52,6 +50,8 @@ public class AppNavigatorFragment extends MvpFragment<AppNavigatorView, AppNavig
private IMogoAnalytics mMogoAnalytics;
private DiscreteScrollView scroller;
private static final int CARD_SIZE = 6;
@Override
protected int getLayoutId() {
return R.layout.module_apps_fragment_apps_navigator;
@@ -83,15 +83,16 @@ public class AppNavigatorFragment extends MvpFragment<AppNavigatorView, AppNavig
ArrayList<Integer> integers = new ArrayList<>(10);
integers.add(R.drawable.module_apps_ic_interest);
integers.add(R.drawable.module_apps_ic_online_car);
integers.add(R.drawable.module_apps_ic_interest);
integers.add(R.drawable.module_apps_ic_news);
integers.add(R.drawable.module_apps_ic_tanlu);
integers.add(R.drawable.module_apps_ic_media_center);
integers.add(R.drawable.module_apps_ic_chat);
integers.add(R.drawable.module_apps_ic_tanlu);
AppIndicatorAdapter appIndicatorAdapter = new AppIndicatorAdapter(getContext(), integers);
scroller.setAdapter(appIndicatorAdapter);
scroller.scrollToPosition(Integer.MAX_VALUE / 2-1);
scroller.scrollToPosition(Integer.MAX_VALUE / 2 - 1);
//mNavigation.setOnClickListener( view -> {
// openSearchPanel();
// trackNavigatorClickEvent( 1 );
@@ -116,6 +117,9 @@ public class AppNavigatorFragment extends MvpFragment<AppNavigatorView, AppNavig
openAppsPanel();
trackNavigatorClickEvent(4);
});
AppServiceHandler.init(getContext());
AppServiceHandler.getMogoCardManager().registerCardChangedListener(TAG, this);
}
private void scrollToCenter(int index) {
@@ -175,7 +179,7 @@ public class AppNavigatorFragment extends MvpFragment<AppNavigatorView, AppNavig
@Override
public void onCurrentItemChanged(@Nullable RecyclerView.ViewHolder viewHolder, int i) {
//AppServiceHandler.getMogoCardManager().invoke(i%CARD_SIZE,"");
}
@Override public void onScrollStart(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
@@ -191,4 +195,16 @@ public class AppNavigatorFragment extends MvpFragment<AppNavigatorView, AppNavig
@Nullable RecyclerView.ViewHolder t1) {
}
@Override public void onSwitched(int position, String moduleName) {
int index = (position - scroller.getCurrentItem() % CARD_SIZE + 2) % CARD_SIZE;
int i = scroller.getCurrentItem() + index;
//DiscreteScrollLayoutManager layoutManager =
// (DiscreteScrollLayoutManager) scroller.getLayoutManager();
//
//layoutManager.smoothScrollToPosition();
Logger.d(TAG, "position" + index + "scroll" + i);
scroller.smoothScrollToPosition(i);
}
}

View File

@@ -0,0 +1,47 @@
package com.mogo.module.apps;
import android.content.Context;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.map.location.IMogoLocationClient;
import com.mogo.map.marker.IMogoMarkerManager;
import com.mogo.map.navi.IMogoNavi;
import com.mogo.map.uicontroller.IMogoMapUIController;
import com.mogo.module.common.entity.MarkerResponse;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.service.IMogoServiceApis;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.analytics.IMogoAnalytics;
import com.mogo.service.cardmanager.IMogoCardManager;
import com.mogo.service.connection.IMogoSocketManager;
import com.mogo.service.imageloader.IMogoImageloader;
import com.mogo.service.map.IMogoMapService;
import com.mogo.service.statusmanager.IMogoStatusManager;
/**
* author : zyz
* e-mail : 1358506549@qq.com
* date : 2020-01-0718:54
* desc : 持有服务接口实例
* version: 1.0
*/
public class AppServiceHandler {
private static final String TAG = "AppServiceHandler";
private static IMogoServiceApis mApis;
private static IMogoCardManager mMogoCardManager;
private static IMogoAnalytics mMogoAnalytics;
public static void init( final Context context ) {
mApis = ( IMogoServiceApis ) ARouter.getInstance().build( MogoServicePaths.PATH_SERVICE_APIS ).navigation( context );
mMogoCardManager = mApis.getCardManagerApi();
mMogoAnalytics = mApis.getAnalyticsApi();
}
public static IMogoCardManager getMogoCardManager() {
return mMogoCardManager;
}
public static IMogoAnalytics getMogoAnalytics() {
return mMogoAnalytics;
}
}

View File

@@ -28,7 +28,7 @@ public class AppIndicatorAdapter extends RecycleBaseAdapter<Integer> {
@Override public void onBindViewHolder(RecycleViewHolder holder, Integer integer) {
ImageView ivIndicator = holder.getView(R.id.module_apps_id_app_icon);
ivIndicator.setImageResource(integer);
holder.setText(R.id.module_apps_id_app_name,names[holder.getLayoutPosition()%5] );
holder.setText(R.id.module_apps_id_app_name,names[holder.getLayoutPosition()%6] );
}
private String[] names=new String[]{"新鲜事","在线车辆","首页","探路","车聊聊"};
private String[] names=new String[]{"在线车辆","新鲜事","首页","媒体中心","车聊聊","探路"};
}

View File

@@ -24,8 +24,9 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.androidxrecyclerview
if (Boolean.valueOf(RELEASE)) {
api rootProject.ext.dependencies.mogomap
api rootProject.ext.dependencies.mogomapapi

View File

@@ -44,7 +44,8 @@ public enum DSVOrientation {
float getDistanceFromCenter(Point center, int viewCenterX, int viewCenterY);
boolean isViewVisible(Point center, int halfWidth, int halfHeight, int endBound, int extraSpace);
boolean isViewVisible(Point center, int halfWidth, int halfHeight, int endBound,
int extraSpace);
boolean hasNewBecomeVisible(DiscreteScrollLayoutManager lm);

View File

@@ -9,6 +9,7 @@ import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.module.common.R;
import com.yarolegovich.discretescrollview.transform.DiscreteScrollItemTransformer;
import com.yarolegovich.discretescrollview.util.ScrollListenerAdapter;
@@ -269,18 +270,18 @@ public class DiscreteScrollView extends RecyclerView {
void onScrollEnd(@NonNull T currentItemHolder, int adapterPosition);
void onScroll(float scrollPosition,
int currentPosition,
int newPosition,
@Nullable T currentHolder,
@Nullable T newCurrent);
int currentPosition,
int newPosition,
@Nullable T currentHolder,
@Nullable T newCurrent);
}
public interface ScrollListener<T extends ViewHolder> {
void onScroll(float scrollPosition,
int currentPosition, int newPosition,
@Nullable T currentHolder,
@Nullable T newCurrent);
int currentPosition, int newPosition,
@Nullable T currentHolder,
@Nullable T newCurrent);
}
public interface OnItemChangedListener<T extends ViewHolder> {

View File

@@ -0,0 +1,179 @@
package com.yarolegovich.discretescrollview;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.module.common.R;
import java.util.Locale;
/**
* Created by yarolegovich on 28-Apr-17.
*/
public class InfiniteScrollAdapter<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<T>
implements DiscreteScrollLayoutManager.InitialPositionProvider {
private static final int CENTER = Integer.MAX_VALUE / 2;
private static final int RESET_BOUND = 100;
public static <T extends RecyclerView.ViewHolder> InfiniteScrollAdapter<T> wrap(
@NonNull RecyclerView.Adapter<T> adapter) {
return new InfiniteScrollAdapter<>(adapter);
}
private RecyclerView.Adapter<T> wrapped;
private DiscreteScrollLayoutManager layoutManager;
public InfiniteScrollAdapter(@NonNull RecyclerView.Adapter<T> wrapped) {
this.wrapped = wrapped;
this.wrapped.registerAdapterDataObserver(new DataSetChangeDelegate());
}
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
wrapped.onAttachedToRecyclerView(recyclerView);
if (recyclerView instanceof DiscreteScrollView) {
layoutManager = (DiscreteScrollLayoutManager) recyclerView.getLayoutManager();
} else {
String msg = recyclerView.getContext().getString(R.string.dsv_ex_msg_adapter_wrong_recycler);
throw new RuntimeException(msg);
}
}
@Override
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
wrapped.onDetachedFromRecyclerView(recyclerView);
layoutManager = null;
}
@Override
public @NonNull T onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return wrapped.onCreateViewHolder(parent, viewType);
}
@Override
public void onBindViewHolder(@NonNull T holder, int position) {
if (isResetRequired(position)) {
int resetPosition = CENTER + mapPositionToReal(layoutManager.getCurrentPosition());
setPosition(resetPosition);
return;
}
wrapped.onBindViewHolder(holder, mapPositionToReal(position));
}
@Override
public int getItemViewType(int position) {
return wrapped.getItemViewType(mapPositionToReal(position));
}
@Override
public int getItemCount() {
return isInfinite() ? Integer.MAX_VALUE : wrapped.getItemCount();
}
public int getRealItemCount() {
return wrapped.getItemCount();
}
public int getRealCurrentPosition() {
return getRealPosition(layoutManager.getCurrentPosition());
}
public int getRealPosition(int position) {
return mapPositionToReal(position);
}
public int getClosestPosition(int position) {
ensureValidPosition(position);
int adapterCurrent = layoutManager.getCurrentPosition();
int current = mapPositionToReal(adapterCurrent);
if (position == current) {
return adapterCurrent;
}
int delta = position - current;
int target = adapterCurrent + delta;
int wraparoundTarget = adapterCurrent + (position > current ?
delta - wrapped.getItemCount() :
wrapped.getItemCount() + delta);
int distance = Math.abs(adapterCurrent - target);
int wraparoundDistance = Math.abs(adapterCurrent - wraparoundTarget);
if (distance == wraparoundDistance) {
//Scroll to the right feels more natural, so prefer it
return target > adapterCurrent ? target : wraparoundTarget;
} else {
return distance < wraparoundDistance ? target : wraparoundTarget;
}
}
private int mapPositionToReal(int position) {
if (position < CENTER) {
int rem = (CENTER - position) % wrapped.getItemCount();
return rem == 0 ? 0 : wrapped.getItemCount() - rem;
} else {
return (position - CENTER) % wrapped.getItemCount();
}
}
private boolean isResetRequired(int requestedPosition) {
return isInfinite()
&& (requestedPosition <= RESET_BOUND
|| requestedPosition >= (Integer.MAX_VALUE - RESET_BOUND));
}
private void ensureValidPosition(int position) {
if (position >= wrapped.getItemCount()) {
throw new IndexOutOfBoundsException(String.format(Locale.US,
"requested position is outside adapter's bounds: position=%d, size=%d",
position, wrapped.getItemCount()));
}
}
private boolean isInfinite() {
return wrapped.getItemCount() > 1;
}
@Override
public int getInitialPosition() {
return isInfinite() ? CENTER : 0;
}
private void setPosition(int position) {
layoutManager.scrollToPosition(position);
}
//TODO: handle proper data set change notifications
private class DataSetChangeDelegate extends RecyclerView.AdapterDataObserver {
@Override
public void onChanged() {
setPosition(getInitialPosition());
notifyDataSetChanged();
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
onChanged();
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
onChanged();
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
onChanged();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
notifyItemRangeChanged(0, getItemCount());
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
notifyItemRangeChanged(0, getItemCount(), payload);
}
}
}

View File

@@ -1,5 +1,6 @@
package com.yarolegovich.discretescrollview.util;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;

View File

@@ -1,3 +1,5 @@
<resources>
<string name="app_name">mogo-module-common</string>
<string name="dsv_ex_msg_dont_set_lm">You should not set LayoutManager on DiscreteScrollView.class instance. Library uses a special one. Just don\'t call the method.</string>
<string name="dsv_ex_msg_adapter_wrong_recycler">InfiniteScrollAdapter is supposed to work only with DiscreteScrollView</string>
</resources>

View File

@@ -34,6 +34,7 @@ import com.mogo.module.main.windowview.WindowViewHandler;
import com.mogo.module.service.ServiceConst;
import com.mogo.service.IMogoServiceApis;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.cardmanager.IMogoCardChangedListener;
import com.mogo.service.cardmanager.IMogoCardManager;
import com.mogo.service.fragmentmanager.IMogoFragmentManager;
import com.mogo.service.intent.IMogoIntentListener;
@@ -55,8 +56,8 @@ import java.util.List;
* 描述:加载各个模块
*/
public class MainActivity extends MvpActivity< MainView, MainPresenter > implements MainView,
IMogoLocationListener,
IMogoMarkerClickListener, IMogoIntentListener {
IMogoLocationListener,
IMogoMarkerClickListener, IMogoIntentListener, IMogoCardChangedListener {
private static final String TAG = "MainActivity";
@@ -245,6 +246,7 @@ public class MainActivity extends MvpActivity< MainView, MainPresenter > impleme
mMogoCardManager = mServiceApis.getCardManagerApi();
mMogoCardManager.registerCardChangedListener(TAG,this);
mMogoFragmentManager = mServiceApis.getFragmentManagerApi();
mMogoFragmentManager.init( this, R.id.module_main_id_search_fragment );
mMogoFragmentManager.registerMainFragmentStackTransactionListener( ( size ) -> {
@@ -442,4 +444,8 @@ public class MainActivity extends MvpActivity< MainView, MainPresenter > impleme
break;
}
}
@Override public void onSwitched(int position, String moduleName) {
mCardsContainer.setCurrentItem( position );
}
}

View File

@@ -4,7 +4,6 @@ include ':foudations:mogo-utils'
include ':services:mogo-service-api'
include ':services:mogo-service'
include ':libraries:mogo-map'
include ':libraries:card-library'
include ':foudations:mogo-commons'
include ':modules:mogo-module-map'
include ':modules:mogo-module-common'