Compare commits
2 Commits
f5eb13a91e
...
f54e65c601
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f54e65c601 | ||
|
|
0c3bc88a29 |
@@ -166,7 +166,7 @@ android {
|
|||||||
// }
|
// }
|
||||||
oss {
|
oss {
|
||||||
applicationId "com.xuebiping.bolizhuzi"
|
applicationId "com.xuebiping.bolizhuzi"
|
||||||
buildConfigField "boolean", "IS_DEV", "false"
|
buildConfigField "boolean", "IS_DEV", "true"
|
||||||
buildConfigField "String", "PRIVACY", '"/index/about/siyuPrivacy.html"'
|
buildConfigField "String", "PRIVACY", '"/index/about/siyuPrivacy.html"'
|
||||||
buildConfigField "String", "AGREEMENT", '"/index/about/siyuAgreement.html"'
|
buildConfigField "String", "AGREEMENT", '"/index/about/siyuAgreement.html"'
|
||||||
buildConfigField "String", "VIP_AGREEMENT", '"/index/about/siyuVipAgreement.html"'
|
buildConfigField "String", "VIP_AGREEMENT", '"/index/about/siyuVipAgreement.html"'
|
||||||
@@ -348,6 +348,7 @@ android {
|
|||||||
implementation project(path: ':storage')
|
implementation project(path: ':storage')
|
||||||
implementation project(path: ':yunxinkit')
|
implementation project(path: ':yunxinkit')
|
||||||
implementation project(':faceunity')
|
implementation project(':faceunity')
|
||||||
|
implementation project(':magicindicator')
|
||||||
//EventBus
|
//EventBus
|
||||||
implementation 'de.greenrobot:eventbus:2.4.0'
|
implementation 'de.greenrobot:eventbus:2.4.0'
|
||||||
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.8.0'
|
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.8.0'
|
||||||
@@ -398,6 +399,9 @@ android {
|
|||||||
implementation 'com.devzld:expandlayout:1.0.0'
|
implementation 'com.devzld:expandlayout:1.0.0'
|
||||||
implementation 'io.github.lucksiege:pictureselector:v3.11.2'
|
implementation 'io.github.lucksiege:pictureselector:v3.11.2'
|
||||||
implementation 'com.github.Dimezis:BlurView:version-3.1.0'
|
implementation 'com.github.Dimezis:BlurView:version-3.1.0'
|
||||||
|
|
||||||
|
implementation "com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-x"
|
||||||
|
implementation "com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6" //3.0.2更换了很多API
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
18
app/oss/release/output-metadata.json
Normal file
18
app/oss/release/output-metadata.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"artifactType": {
|
||||||
|
"type": "APK",
|
||||||
|
"kind": "Directory"
|
||||||
|
},
|
||||||
|
"applicationId": "com.xuebiping.bolizhuzi",
|
||||||
|
"variantName": "ossRelease",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "SINGLE",
|
||||||
|
"filters": [],
|
||||||
|
"versionCode": 1,
|
||||||
|
"versionName": "1.0.0",
|
||||||
|
"outputFile": "siyu_v1.0.0_oss_release.apk"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
app/oss/release/siyu_v1.0.0_oss_release.apk
Normal file
BIN
app/oss/release/siyu_v1.0.0_oss_release.apk
Normal file
Binary file not shown.
@@ -136,7 +136,7 @@ public class DynamicsAdapter extends BaseAdapter {
|
|||||||
public View getView(int i, View view, ViewGroup viewGroup) {
|
public View getView(int i, View view, ViewGroup viewGroup) {
|
||||||
Holder holder = null;
|
Holder holder = null;
|
||||||
if (null == view) {
|
if (null == view) {
|
||||||
view = View.inflate(mContext, R.layout.item_dynamic_list1, null);
|
view = View.inflate(mContext, R.layout.item_dynamic_list, null);
|
||||||
holder = initView(view);
|
holder = initView(view);
|
||||||
} else {
|
} else {
|
||||||
holder = (Holder) view.getTag(R.id.tag_second);
|
holder = (Holder) view.getTag(R.id.tag_second);
|
||||||
@@ -155,7 +155,7 @@ public class DynamicsAdapter extends BaseAdapter {
|
|||||||
holder.newPeopleImageView.setVisibility(View.GONE);
|
holder.newPeopleImageView.setVisibility(View.GONE);
|
||||||
holder.realPeopleImageView.setVisibility(View.GONE);
|
holder.realPeopleImageView.setVisibility(View.GONE);
|
||||||
|
|
||||||
holder.tv_see_count.setText("已有"+bean.getLike_count()+"次浏览");
|
// holder.tv_see_count.setText("已有"+bean.getLike_count()+"次浏览");
|
||||||
|
|
||||||
if (bean.getGender() == 1) {
|
if (bean.getGender() == 1) {
|
||||||
holder.realPeopleImageView.setVisibility(View.VISIBLE);
|
holder.realPeopleImageView.setVisibility(View.VISIBLE);
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.xuebiping.bolizhuzi.controller.main.adapter;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||||
|
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
|
||||||
|
import com.facebook.drawee.view.SimpleDraweeView;
|
||||||
|
import com.xuebiping.bolizhuzi.R;
|
||||||
|
import com.xuebiping.bolizhuzi.model.main.LookMeBean;
|
||||||
|
import com.xuebiping.bolizhuzi.utils.StrU;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class MainLookMeAdapter extends BaseQuickAdapter<LookMeBean, BaseViewHolder> {
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
public MainLookMeAdapter(int layoutResId, Context context) {
|
||||||
|
super(layoutResId);
|
||||||
|
this.mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void convert(@NotNull BaseViewHolder baseViewHolder, LookMeBean lookMeBean) {
|
||||||
|
SimpleDraweeView list_photo = baseViewHolder.getView(R.id.list_photo);
|
||||||
|
|
||||||
|
list_photo.setImageURI(StrU.getResourcePath(lookMeBean.getAvatar_url(), mContext));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.xuebiping.bolizhuzi.controller.main.adapter;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.titles.ColorTransitionPagerTitleView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 带颜色渐变和缩放的指示器标题
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class ScaleTransitionPagerTitleView extends ColorTransitionPagerTitleView {
|
||||||
|
private float mMinScale = 0.75f;
|
||||||
|
|
||||||
|
public ScaleTransitionPagerTitleView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {
|
||||||
|
super.onEnter(index, totalCount, enterPercent, leftToRight); // 实现颜色渐变
|
||||||
|
setScaleX(mMinScale + (1.0f - mMinScale) * enterPercent);
|
||||||
|
setScaleY(mMinScale + (1.0f - mMinScale) * enterPercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {
|
||||||
|
super.onLeave(index, totalCount, leavePercent, leftToRight); // 实现颜色渐变
|
||||||
|
setScaleX(1.0f + (mMinScale - 1.0f) * leavePercent);
|
||||||
|
setScaleY(1.0f + (mMinScale - 1.0f) * leavePercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMinScale() {
|
||||||
|
return mMinScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinScale(float minScale) {
|
||||||
|
mMinScale = minScale;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.xuebiping.bolizhuzi.model.main;
|
||||||
|
|
||||||
|
public class LookMeBean {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String avatar_url;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAvatar_url() {
|
||||||
|
return avatar_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvatar_url(String avatar_url) {
|
||||||
|
this.avatar_url = avatar_url;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.xuebiping.bolizhuzi.model.main;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LookMeListBean {
|
||||||
|
|
||||||
|
private List<LookMeBean> list = new ArrayList<>();
|
||||||
|
|
||||||
|
public List<LookMeBean> getList() {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setList(List<LookMeBean> list) {
|
||||||
|
this.list = list;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,7 +31,7 @@ public class DynamicDetailTwoActivity extends BaseActivity {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_dynamic_detail_two);
|
setContentView(R.layout.activity_dynamic_detail_two);
|
||||||
bean = getIntent().getParcelableExtra("bean");
|
bean = (DynamicsItemBean) getIntent().getSerializableExtra("bean");
|
||||||
mImageList.add(bean);
|
mImageList.add(bean);
|
||||||
setTitleName("动态详情");
|
setTitleName("动态详情");
|
||||||
|
|
||||||
|
|||||||
@@ -178,15 +178,15 @@ public class RecentDynamicFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onDetailClicked(int position, String id) {
|
public void onDetailClicked(int position, String id) {
|
||||||
detailPosition = position;
|
detailPosition = position;
|
||||||
/*Intent intent = new Intent(getContext(), DynamicDetailActivity.class);
|
Intent intent = new Intent(getContext(), DynamicDetailActivity.class);
|
||||||
intent.putExtra("dynamic_id", id);
|
intent.putExtra("dynamic_id", id);
|
||||||
intent.putExtra("dynamic_from", 0);
|
intent.putExtra("dynamic_from", 0);
|
||||||
startActivity(intent);*/
|
|
||||||
|
|
||||||
DynamicsItemBean itemBean = mAdapter.getmDynamicsItemList().get(position);
|
|
||||||
Intent intent = new Intent(getContext(), DynamicDetailTwoActivity.class);
|
|
||||||
intent.putExtra("bean", (Parcelable) itemBean);
|
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
|
||||||
|
// DynamicsItemBean itemBean = mAdapter.getmDynamicsItemList().get(position);
|
||||||
|
// Intent intent = new Intent(getContext(), DynamicDetailTwoActivity.class);
|
||||||
|
// intent.putExtra("bean", itemBean);
|
||||||
|
// startActivity(intent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package com.xuebiping.bolizhuzi.view.main;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
|
||||||
|
import com.scwang.smartrefresh.layout.api.RefreshLayout;
|
||||||
|
import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener;
|
||||||
|
import com.xuebiping.bolizhuzi.R;
|
||||||
|
import com.xuebiping.bolizhuzi.controller.main.adapter.MainLookMeAdapter;
|
||||||
|
import com.xuebiping.bolizhuzi.model.main.LookMeBean;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LookMeFragment extends Fragment implements OnRefreshLoadMoreListener {
|
||||||
|
|
||||||
|
private View v;
|
||||||
|
|
||||||
|
private SmartRefreshLayout mSmart_refresh;
|
||||||
|
private RecyclerView mRv_recommend_list;
|
||||||
|
private MainLookMeAdapter mMainLookMeAdapter;
|
||||||
|
|
||||||
|
private int mPage = 1;
|
||||||
|
private List<LookMeBean> mData = new ArrayList<>();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@org.jetbrains.annotations.Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
|
||||||
|
v = inflater.inflate(R.layout.fragment_look_me, container, false);
|
||||||
|
initView(v);
|
||||||
|
getData(mPage);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initView(View v) {
|
||||||
|
mSmart_refresh = v.findViewById(R.id.smart_refresh);
|
||||||
|
mRv_recommend_list = v.findViewById(R.id.rv_recommend_list);
|
||||||
|
mRv_recommend_list.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||||
|
mMainLookMeAdapter = new MainLookMeAdapter(R.layout.item_main_look_me, getActivity());
|
||||||
|
mRv_recommend_list.setAdapter(mMainLookMeAdapter);
|
||||||
|
|
||||||
|
mSmart_refresh.setOnRefreshLoadMoreListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getData(int page) {
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
|
||||||
|
LookMeBean lookMeBean = new LookMeBean();
|
||||||
|
lookMeBean.setId(i + "");
|
||||||
|
lookMeBean.setAvatar_url("uploads/admin/202403/25/04cf409ab9148f11c0052bb254b5c155.jpg");
|
||||||
|
mData.add(lookMeBean);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
finishFresh();
|
||||||
|
mMainLookMeAdapter.setList(mData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finishFresh() {
|
||||||
|
mSmart_refresh.finishLoadMore();
|
||||||
|
mSmart_refresh.finishRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) {
|
||||||
|
mPage++;
|
||||||
|
getData(mPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) {
|
||||||
|
mPage = 1;
|
||||||
|
getData(mPage);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -168,7 +168,7 @@ public class MainActivity extends BaseActivity implements DemoHelper.AppIdsUpdat
|
|||||||
private LuckFragment luckFragment;
|
private LuckFragment luckFragment;
|
||||||
private SwipeCardFragment swipeCardFragment;
|
private SwipeCardFragment swipeCardFragment;
|
||||||
private DynamicViewPagerFragment mDynamicViewPagerFragment;
|
private DynamicViewPagerFragment mDynamicViewPagerFragment;
|
||||||
private MainRecommendFragment mMainRecommendFragment;
|
private MainRecommend2Fragment mMainRecommendFragment;
|
||||||
private MainMessageFragment mMainMessageFragment;
|
private MainMessageFragment mMainMessageFragment;
|
||||||
private SettingFragment mSettingFragment;
|
private SettingFragment mSettingFragment;
|
||||||
private Disposable mDisposable;
|
private Disposable mDisposable;
|
||||||
@@ -280,27 +280,27 @@ public class MainActivity extends BaseActivity implements DemoHelper.AppIdsUpdat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
protected void onNewIntent(Intent intent) {
|
// protected void onNewIntent(Intent intent) {
|
||||||
super.onNewIntent(intent);
|
// super.onNewIntent(intent);
|
||||||
boolean isFormTask = intent.getBooleanExtra("isFormTask", false);
|
// boolean isFormTask = intent.getBooleanExtra("isFormTask", false);
|
||||||
boolean isMain = intent.getBooleanExtra("isMain", false);
|
// boolean isMain = intent.getBooleanExtra("isMain", false);
|
||||||
if (isFormTask) {
|
// if (isFormTask) {
|
||||||
mBottomTab.change(1);
|
// mBottomTab.change(1);
|
||||||
}
|
// }
|
||||||
if (isMain) {
|
// if (isMain) {
|
||||||
int marketStatus = NoClearSPUtils.getInt(this, Constans.MARKET_STATUS, 0);
|
// int marketStatus = NoClearSPUtils.getInt(this, Constans.MARKET_STATUS, 0);
|
||||||
if (marketStatus == 0 || SPUtils.getInt(this, ConsUser.TYPE) == 2) {
|
// if (marketStatus == 0 || SPUtils.getInt(this, ConsUser.TYPE) == 2) {
|
||||||
mBottomTab.change(0);
|
// mBottomTab.change(0);
|
||||||
} else {
|
// } else {
|
||||||
if (UserManager.getUserInfo().isWomen()) {
|
// if (UserManager.getUserInfo().isWomen()) {
|
||||||
mBottomTab.change(0);
|
// mBottomTab.change(0);
|
||||||
} else {
|
// } else {
|
||||||
mBottomTab.change(2);
|
// mBottomTab.change(2);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调起使用这个会弹出hms 下载框
|
* 调起使用这个会弹出hms 下载框
|
||||||
@@ -876,9 +876,9 @@ public class MainActivity extends BaseActivity implements DemoHelper.AppIdsUpdat
|
|||||||
if (position == currentPosition) { //第二次点击
|
if (position == currentPosition) { //第二次点击
|
||||||
if (position == 0) {
|
if (position == 0) {
|
||||||
if (isOne) {
|
if (isOne) {
|
||||||
if (null != mMainRecommendFragment) {
|
// if (null != mMainRecommendFragment) {
|
||||||
mMainRecommendFragment.clickRefresh();
|
// mMainRecommendFragment.clickRefresh();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
isOne = true;
|
isOne = true;
|
||||||
} else if (position == 1) {
|
} else if (position == 1) {
|
||||||
@@ -888,9 +888,9 @@ public class MainActivity extends BaseActivity implements DemoHelper.AppIdsUpdat
|
|||||||
}
|
}
|
||||||
} else if (position == 0) { //重新点击回来,检测版本更新
|
} else if (position == 0) { //重新点击回来,检测版本更新
|
||||||
checkUpdate();
|
checkUpdate();
|
||||||
if (null != mMainRecommendFragment) {
|
// if (null != mMainRecommendFragment) {
|
||||||
mMainRecommendFragment.RefreshFragment();
|
// mMainRecommendFragment.RefreshFragment();
|
||||||
}
|
// }
|
||||||
} else if (position == 3) {
|
} else if (position == 3) {
|
||||||
// MaleToast.showMessage(MainActivity.this,"点击了消息");
|
// MaleToast.showMessage(MainActivity.this,"点击了消息");
|
||||||
getGreet();
|
getGreet();
|
||||||
@@ -1060,7 +1060,7 @@ public class MainActivity extends BaseActivity implements DemoHelper.AppIdsUpdat
|
|||||||
mDynamicViewPagerFragment = new DynamicViewPagerFragment();
|
mDynamicViewPagerFragment = new DynamicViewPagerFragment();
|
||||||
}
|
}
|
||||||
if (mMainRecommendFragment == null) {
|
if (mMainRecommendFragment == null) {
|
||||||
mMainRecommendFragment = new MainRecommendFragment();
|
mMainRecommendFragment = new MainRecommend2Fragment();
|
||||||
}
|
}
|
||||||
if (mMainMessageFragment == null) {
|
if (mMainMessageFragment == null) {
|
||||||
mMainMessageFragment = new MainMessageFragment();
|
mMainMessageFragment = new MainMessageFragment();
|
||||||
@@ -1069,24 +1069,25 @@ public class MainActivity extends BaseActivity implements DemoHelper.AppIdsUpdat
|
|||||||
mSettingFragment = new SettingFragment();
|
mSettingFragment = new SettingFragment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mBottomTab.addTab(mMainRecommendFragment);
|
||||||
|
mBottomTab.addTab(mDynamicViewPagerFragment);
|
||||||
if (marketStatus == 0 || SPUtils.getInt(this, ConsUser.TYPE) == 2) {
|
if (marketStatus == 0 || SPUtils.getInt(this, ConsUser.TYPE) == 2) {
|
||||||
mBottomTab.addTab(swipeCardFragment);
|
mBottomTab.addTab(swipeCardFragment);
|
||||||
} else {
|
} else {
|
||||||
mBottomTab.addTab(luckFragment);
|
mBottomTab.addTab(luckFragment);
|
||||||
}
|
}
|
||||||
mBottomTab.addTab(mDynamicViewPagerFragment);
|
|
||||||
mBottomTab.addTab(mMainRecommendFragment);
|
|
||||||
mBottomTab.addTab(mMainMessageFragment);
|
mBottomTab.addTab(mMainMessageFragment);
|
||||||
mBottomTab.addTab(mSettingFragment);
|
mBottomTab.addTab(mSettingFragment);
|
||||||
if (marketStatus == 0 || SPUtils.getInt(this, ConsUser.TYPE) == 2) {
|
mBottomTab.change(0);
|
||||||
mBottomTab.change(0);
|
// if (marketStatus == 0 || SPUtils.getInt(this, ConsUser.TYPE) == 2) {
|
||||||
} else {
|
// mBottomTab.change(0);
|
||||||
if (UserManager.getUserInfo().isWomen()) {
|
// } else {
|
||||||
mBottomTab.change(0);
|
// if (UserManager.getUserInfo().isWomen()) {
|
||||||
} else {
|
// mBottomTab.change(0);
|
||||||
mBottomTab.change(2);
|
// } else {
|
||||||
}
|
// mBottomTab.change(2);
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// @Override
|
// @Override
|
||||||
|
|||||||
@@ -0,0 +1,267 @@
|
|||||||
|
package com.xuebiping.bolizhuzi.view.main;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.animation.AccelerateInterpolator;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
|
import com.fengliyan.uikit.UiUtils;
|
||||||
|
import com.fengliyan.uikit.toast.MaleToast;
|
||||||
|
import com.xuebiping.bolizhuzi.R;
|
||||||
|
import com.xuebiping.bolizhuzi.controller.main.adapter.MainViewPagerAdapter;
|
||||||
|
import com.xuebiping.bolizhuzi.controller.main.adapter.ScaleTransitionPagerTitleView;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.MagicIndicator;
|
||||||
|
import net.lucode.hackware.magicindicator.ViewPagerHelper;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.UIUtil;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.CommonNavigator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.CommonNavigatorAdapter;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerTitleView;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators.LinePagerIndicator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.titles.CommonPagerTitleView;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.titles.SimplePagerTitleView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MainRecommend2Fragment extends Fragment implements View.OnClickListener {
|
||||||
|
|
||||||
|
private View v;
|
||||||
|
private RelativeLayout mRl_home_search;
|
||||||
|
private LinearLayout mLl_select;
|
||||||
|
private MagicIndicator mMagicIndicator;
|
||||||
|
private ViewPager mMainViewPager;
|
||||||
|
|
||||||
|
private MainViewPagerAdapter mViewPagerAdapter;
|
||||||
|
private List<Fragment> mChannelFragments = new ArrayList<>();
|
||||||
|
private List<String> mDataList = new ArrayList<>();
|
||||||
|
private int mIndex = 1;
|
||||||
|
|
||||||
|
private LookMeFragment mLookMeFragment;
|
||||||
|
private RecommendFragment1 mLookMeFragment1;
|
||||||
|
private DefaultRecommendFragment mLookMeFragment2;
|
||||||
|
private MainRecommendActiveFragment mLookMeFragment3;
|
||||||
|
private MainRecommendPeopleFragment mLookMeFragment4;
|
||||||
|
private MainRecommendCityFragment mLookMeFragment5;
|
||||||
|
private LookMeFragment mLookMeFragment6;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
v = inflater.inflate(R.layout.fragment_main_recommend2, container, false);
|
||||||
|
initView(v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initView(View v) {
|
||||||
|
mLl_select = v.findViewById(R.id.ll_select);
|
||||||
|
mRl_home_search = v.findViewById(R.id.rl_home_search);
|
||||||
|
mMagicIndicator = v.findViewById(R.id.magic_indicator);
|
||||||
|
mMainViewPager = v.findViewById(R.id.main_view_pager);
|
||||||
|
|
||||||
|
mLl_select.setOnClickListener(this);
|
||||||
|
mRl_home_search.setOnClickListener(this);
|
||||||
|
|
||||||
|
mLookMeFragment = new LookMeFragment();
|
||||||
|
mLookMeFragment1 = new RecommendFragment1();
|
||||||
|
mLookMeFragment2 = new DefaultRecommendFragment();
|
||||||
|
mLookMeFragment3 = new MainRecommendActiveFragment();
|
||||||
|
mLookMeFragment4 = new MainRecommendPeopleFragment();
|
||||||
|
mLookMeFragment5 = new MainRecommendCityFragment();
|
||||||
|
mLookMeFragment6 = new LookMeFragment();
|
||||||
|
|
||||||
|
mChannelFragments.add(mLookMeFragment);
|
||||||
|
mChannelFragments.add(mLookMeFragment1);
|
||||||
|
mChannelFragments.add(mLookMeFragment2);
|
||||||
|
mChannelFragments.add(mLookMeFragment3);
|
||||||
|
mChannelFragments.add(mLookMeFragment4);
|
||||||
|
mChannelFragments.add(mLookMeFragment5);
|
||||||
|
mChannelFragments.add(mLookMeFragment6);
|
||||||
|
|
||||||
|
mViewPagerAdapter = new MainViewPagerAdapter(getChildFragmentManager(),
|
||||||
|
mChannelFragments);
|
||||||
|
mMainViewPager.setAdapter(mViewPagerAdapter);
|
||||||
|
|
||||||
|
initMagicIndicator();
|
||||||
|
|
||||||
|
mMainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
// if (position == 3) {
|
||||||
|
// isReClick = true;
|
||||||
|
// mIv_more_city.setVisibility(View.VISIBLE);
|
||||||
|
// } else {
|
||||||
|
// isReClick = false;
|
||||||
|
// mIv_more_city.setVisibility(View.INVISIBLE);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
mIndex = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mViewPagerAdapter.notifyDataSetChanged();
|
||||||
|
mMainViewPager.setCurrentItem(mIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initMagicIndicator() {
|
||||||
|
mDataList.clear();
|
||||||
|
mDataList.add("看过我");
|
||||||
|
mDataList.add("推荐");
|
||||||
|
mDataList.add("语聊");
|
||||||
|
mDataList.add("新人");
|
||||||
|
mDataList.add("五星");
|
||||||
|
mDataList.add("四星");
|
||||||
|
mDataList.add("三星");
|
||||||
|
|
||||||
|
CommonNavigator commonNavigator = new CommonNavigator(getActivity());
|
||||||
|
commonNavigator.setAdapter(new CommonNavigatorAdapter() {
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return mDataList == null ? 0 : mDataList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPagerTitleView getTitleView(Context context, final int index) {
|
||||||
|
SimplePagerTitleView simplePagerTitleView = new ScaleTransitionPagerTitleView(context);
|
||||||
|
simplePagerTitleView.setText(mDataList.get(index));
|
||||||
|
simplePagerTitleView.setTextSize(20);
|
||||||
|
simplePagerTitleView.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));//加粗
|
||||||
|
simplePagerTitleView.setNormalColor(Color.parseColor("#33000000"));
|
||||||
|
simplePagerTitleView.setSelectedColor(Color.parseColor("#000000"));
|
||||||
|
simplePagerTitleView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
// if (isReClick && index == 3) {
|
||||||
|
// Intent intent = new Intent(getActivity(), CityPickerActivity.class);
|
||||||
|
// startActivityForResult(intent, RECOMMEND_CHANGE_CITY_REQUEST);
|
||||||
|
// } else {
|
||||||
|
// mMainViewPager.setCurrentItem(index);
|
||||||
|
// }
|
||||||
|
Log.d("nail", "onClick: " + index);
|
||||||
|
mMainViewPager.setCurrentItem(index);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return simplePagerTitleView;
|
||||||
|
|
||||||
|
// CommonPagerTitleView commonPagerTitleView = new CommonPagerTitleView(getActivity());
|
||||||
|
// commonPagerTitleView.setContentView(R.layout.main_pager_title_layout);
|
||||||
|
//
|
||||||
|
// // 初始化
|
||||||
|
// ImageView iv_selected = (ImageView) commonPagerTitleView.findViewById(R.id.iv_selected);
|
||||||
|
// ImageView iv_no_selected = (ImageView) commonPagerTitleView.findViewById(R.id.iv_no_selected);
|
||||||
|
// final TextView titleText = (TextView) commonPagerTitleView.findViewById(R.id.title_text);
|
||||||
|
// titleText.setText(mDataList.get(index));
|
||||||
|
// commonPagerTitleView.setPadding(UIUtil.dip2px(context, 5),
|
||||||
|
// UIUtil.dip2px(context, 0),
|
||||||
|
// UIUtil.dip2px(context, 5),
|
||||||
|
// UIUtil.dip2px(context, 0));
|
||||||
|
//
|
||||||
|
// commonPagerTitleView.setOnPagerTitleChangeListener(new CommonPagerTitleView.OnPagerTitleChangeListener() {
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void onSelected(int index, int totalCount) {
|
||||||
|
// titleText.setTextSize(16);
|
||||||
|
// titleText.setTextColor(Color.parseColor("#ffffff"));
|
||||||
|
// titleText.setTypeface(Typeface.DEFAULT_BOLD);
|
||||||
|
// iv_selected.setVisibility(View.VISIBLE);
|
||||||
|
// iv_no_selected.setVisibility(View.INVISIBLE);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void onDeselected(int index, int totalCount) {
|
||||||
|
// titleText.setTextSize(16);
|
||||||
|
// titleText.setTextColor(Color.parseColor("#33000000"));
|
||||||
|
// titleText.setTypeface(Typeface.DEFAULT);
|
||||||
|
// iv_selected.setVisibility(View.INVISIBLE);
|
||||||
|
// iv_no_selected.setVisibility(View.VISIBLE);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {
|
||||||
|
// // rl_title_bg.setScaleX(1.3f + (0.8f - 1.3f) * leavePercent);
|
||||||
|
// //rl_title_bg.setScaleY(1.3f + (0.8f - 1.3f) * leavePercent);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {
|
||||||
|
// // rl_title_bg.setScaleX(0.8f + (1.3f - 0.8f) * enterPercent);
|
||||||
|
// // rl_title_bg.setScaleY(0.8f + (1.3f - 0.8f) * enterPercent);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// commonPagerTitleView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
// @Override
|
||||||
|
// public void onClick(View v) {
|
||||||
|
// if (isReClick && index == 3) {
|
||||||
|
// Intent intent = new Intent(getActivity(), CityPickerActivity.class);
|
||||||
|
// startActivityForResult(intent, RECOMMEND_CHANGE_CITY_REQUEST);
|
||||||
|
// } else {
|
||||||
|
// mMainViewPager.setCurrentItem(index);
|
||||||
|
// }
|
||||||
|
// mMainViewPager.setCurrentItem(index);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// return commonPagerTitleView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPagerIndicator getIndicator(Context context) {
|
||||||
|
// LinePagerIndicator indicator = new LinePagerIndicator(context);
|
||||||
|
// indicator.setMode(LinePagerIndicator.MODE_WRAP_CONTENT);
|
||||||
|
// indicator.setLineHeight(UIUtil.dip2px(context, 10));
|
||||||
|
// indicator.setLineWidth(UIUtil.dip2px(context, 20));
|
||||||
|
// indicator.setRoundRadius(UIUtil.dip2px(context, 0));
|
||||||
|
// indicator.setStartInterpolator(new AccelerateInterpolator());
|
||||||
|
// indicator.setEndInterpolator(new DecelerateInterpolator(2.0f));
|
||||||
|
// indicator.setColors(getResources().getColor(R.color.yellow_ffd33e));
|
||||||
|
// indicator.setYOffset(UIUtil.dip2px(context, 10));
|
||||||
|
// indicator.setXOffset(0);
|
||||||
|
|
||||||
|
LinePagerIndicator indicator = new LinePagerIndicator(context);
|
||||||
|
indicator.setColors(getResources().getColor(R.color.yellow_ffd33e));
|
||||||
|
indicator.setLineHeight(UIUtil.dip2px(context, 10));
|
||||||
|
indicator.setMode(LinePagerIndicator.MODE_WRAP_CONTENT);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mMagicIndicator.setNavigator(commonNavigator);
|
||||||
|
ViewPagerHelper.bind(mMagicIndicator, mMainViewPager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
if (view == mRl_home_search) {
|
||||||
|
MaleToast.showMessage(getActivity(), "搜索");
|
||||||
|
}else if (view == mLl_select) {
|
||||||
|
MaleToast.showMessage(getActivity(), "筛选");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 647 B |
8
app/src/main/res/drawable/look_me_online_bg.xml
Normal file
8
app/src/main/res/drawable/look_me_online_bg.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
|
<solid android:color="#6CE4B7"/>
|
||||||
|
<corners android:radius="@dimen/dp16"/>
|
||||||
|
|
||||||
|
</shape>
|
||||||
75
app/src/main/res/layout/fragment_look_me.xml
Normal file
75
app/src/main/res/layout/fragment_look_me.xml
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:viewBindingIgnore="true">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_content_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.scwang.smartrefresh.layout.SmartRefreshLayout
|
||||||
|
android:id="@+id/smart_refresh"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<com.scwang.smartrefresh.layout.header.ClassicsHeader
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srlEnableLastTime="false" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/rl_no_data"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="@dimen/dp100"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="@dimen/dp150"
|
||||||
|
android:layout_height="@dimen/dp88"
|
||||||
|
android:src="@mipmap/icon_img_no_black" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/dp5"
|
||||||
|
android:text="暂无数据"
|
||||||
|
android:textColor="@color/three_text"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rv_recommend_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="@dimen/dp_10" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.scwang.smartrefresh.layout.footer.ClassicsFooter
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
65
app/src/main/res/layout/fragment_main_recommend2.xml
Normal file
65
app/src/main/res/layout/fragment_main_recommend2.xml
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/rl_head"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dp48">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_select"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="筛选"
|
||||||
|
android:textColor="#ffe472ed"
|
||||||
|
android:textSize="13sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_marginLeft="5dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:src="@drawable/ic_main_select_man_and_woman"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<net.lucode.hackware.magicindicator.MagicIndicator
|
||||||
|
android:id="@+id/magic_indicator"
|
||||||
|
android:layout_width="1000dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_gravity="center_vertical" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/rl_home_search"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_width="@dimen/dp44"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_home_search" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.viewpager.widget.ViewPager
|
||||||
|
android:id="@+id/main_view_pager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_below="@+id/rl_head" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
108
app/src/main/res/layout/item_main_look_me.xml
Normal file
108
app/src/main/res/layout/item_main_look_me.xml
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
xmlns:fresco="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_marginTop="@dimen/dp10"
|
||||||
|
android:layout_marginBottom="@dimen/dp10"
|
||||||
|
android:layout_marginLeft="@dimen/dp16"
|
||||||
|
android:layout_marginRight="@dimen/dp16"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="@dimen/dp50"
|
||||||
|
android:layout_height="@dimen/dp50">
|
||||||
|
|
||||||
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
|
android:id="@+id/list_photo"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
fresco:roundAsCircle="true" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/rl_online_bg"
|
||||||
|
android:layout_width="@dimen/dp30"
|
||||||
|
android:layout_height="@dimen/dp16"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:background="@drawable/look_me_online_bg">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_online"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:text="在线"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="10sp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginLeft="@dimen/dp12"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="瑞恩 Rain"
|
||||||
|
android:textColor="@color/one_text"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/dp6"
|
||||||
|
android:text="1小时前在线"
|
||||||
|
android:textColor="@color/three_text"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="共 "
|
||||||
|
android:textColor="@color/three_text"
|
||||||
|
android:textSize="14sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_visit_number"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="1次"
|
||||||
|
android:textColor="@color/yellow_ffd33e"
|
||||||
|
android:textSize="14sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text=" 访问"
|
||||||
|
android:textColor="@color/three_text"
|
||||||
|
android:textSize="14sp"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
BIN
app/src/main/res/mipmap-xxhdpi/icon_img_no_black.png
Normal file
BIN
app/src/main/res/mipmap-xxhdpi/icon_img_no_black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
20
magicindicator/build.gradle
Normal file
20
magicindicator/build.gradle
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 28
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion 21
|
||||||
|
targetSdkVersion 28
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||||
|
}
|
||||||
1
magicindicator/src/main/AndroidManifest.xml
Normal file
1
magicindicator/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<manifest package="net.lucode.hackware.magicindicator" />
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
package net.lucode.hackware.magicindicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.model.PositionData;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使得MagicIndicator在FragmentContainer中使用
|
||||||
|
* Created by hackware on 2016/9/4.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||||
|
public class FragmentContainerHelper {
|
||||||
|
private List<MagicIndicator> mMagicIndicators = new ArrayList<MagicIndicator>();
|
||||||
|
private ValueAnimator mScrollAnimator;
|
||||||
|
private int mLastSelectedIndex;
|
||||||
|
private int mDuration = 150;
|
||||||
|
private Interpolator mInterpolator = new AccelerateDecelerateInterpolator();
|
||||||
|
|
||||||
|
private Animator.AnimatorListener mAnimatorListener = new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
dispatchPageScrollStateChanged(ScrollState.SCROLL_STATE_IDLE);
|
||||||
|
mScrollAnimator = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private ValueAnimator.AnimatorUpdateListener mAnimatorUpdateListener = new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
float positionOffsetSum = (Float) animation.getAnimatedValue();
|
||||||
|
int position = (int) positionOffsetSum;
|
||||||
|
float positionOffset = positionOffsetSum - position;
|
||||||
|
if (positionOffsetSum < 0) {
|
||||||
|
position = position - 1;
|
||||||
|
positionOffset = 1.0f + positionOffset;
|
||||||
|
}
|
||||||
|
dispatchPageScrolled(position, positionOffset, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public FragmentContainerHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public FragmentContainerHelper(MagicIndicator magicIndicator) {
|
||||||
|
mMagicIndicators.add(magicIndicator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IPagerIndicator支持弹性效果的辅助方法
|
||||||
|
*
|
||||||
|
* @param positionDataList
|
||||||
|
* @param index
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static PositionData getImitativePositionData(List<PositionData> positionDataList, int index) {
|
||||||
|
if (index >= 0 && index <= positionDataList.size() - 1) { // 越界后,返回假的PositionData
|
||||||
|
return positionDataList.get(index);
|
||||||
|
} else {
|
||||||
|
PositionData result = new PositionData();
|
||||||
|
PositionData referenceData;
|
||||||
|
int offset;
|
||||||
|
if (index < 0) {
|
||||||
|
offset = index;
|
||||||
|
referenceData = positionDataList.get(0);
|
||||||
|
} else {
|
||||||
|
offset = index - positionDataList.size() + 1;
|
||||||
|
referenceData = positionDataList.get(positionDataList.size() - 1);
|
||||||
|
}
|
||||||
|
result.mLeft = referenceData.mLeft + offset * referenceData.width();
|
||||||
|
result.mTop = referenceData.mTop;
|
||||||
|
result.mRight = referenceData.mRight + offset * referenceData.width();
|
||||||
|
result.mBottom = referenceData.mBottom;
|
||||||
|
result.mContentLeft = referenceData.mContentLeft + offset * referenceData.width();
|
||||||
|
result.mContentTop = referenceData.mContentTop;
|
||||||
|
result.mContentRight = referenceData.mContentRight + offset * referenceData.width();
|
||||||
|
result.mContentBottom = referenceData.mContentBottom;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handlePageSelected(int selectedIndex) {
|
||||||
|
handlePageSelected(selectedIndex, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handlePageSelected(int selectedIndex, boolean smooth) {
|
||||||
|
if (mLastSelectedIndex == selectedIndex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (smooth) {
|
||||||
|
if (mScrollAnimator == null || !mScrollAnimator.isRunning()) {
|
||||||
|
dispatchPageScrollStateChanged(ScrollState.SCROLL_STATE_SETTLING);
|
||||||
|
}
|
||||||
|
dispatchPageSelected(selectedIndex);
|
||||||
|
float currentPositionOffsetSum = mLastSelectedIndex;
|
||||||
|
if (mScrollAnimator != null) {
|
||||||
|
currentPositionOffsetSum = (Float) mScrollAnimator.getAnimatedValue();
|
||||||
|
mScrollAnimator.cancel();
|
||||||
|
mScrollAnimator = null;
|
||||||
|
}
|
||||||
|
mScrollAnimator = new ValueAnimator();
|
||||||
|
mScrollAnimator.setFloatValues(currentPositionOffsetSum, selectedIndex); // position = selectedIndex, positionOffset = 0.0f
|
||||||
|
mScrollAnimator.addUpdateListener(mAnimatorUpdateListener);
|
||||||
|
mScrollAnimator.addListener(mAnimatorListener);
|
||||||
|
mScrollAnimator.setInterpolator(mInterpolator);
|
||||||
|
mScrollAnimator.setDuration(mDuration);
|
||||||
|
mScrollAnimator.start();
|
||||||
|
} else {
|
||||||
|
dispatchPageSelected(selectedIndex);
|
||||||
|
if (mScrollAnimator != null && mScrollAnimator.isRunning()) {
|
||||||
|
dispatchPageScrolled(mLastSelectedIndex, 0.0f, 0);
|
||||||
|
}
|
||||||
|
dispatchPageScrollStateChanged(ScrollState.SCROLL_STATE_IDLE);
|
||||||
|
dispatchPageScrolled(selectedIndex, 0.0f, 0);
|
||||||
|
}
|
||||||
|
mLastSelectedIndex = selectedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDuration(int duration) {
|
||||||
|
mDuration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterpolator(Interpolator interpolator) {
|
||||||
|
if (interpolator == null) {
|
||||||
|
mInterpolator = new AccelerateDecelerateInterpolator();
|
||||||
|
} else {
|
||||||
|
mInterpolator = interpolator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void attachMagicIndicator(MagicIndicator magicIndicator) {
|
||||||
|
mMagicIndicators.add(magicIndicator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dispatchPageSelected(int pageIndex) {
|
||||||
|
for (MagicIndicator magicIndicator : mMagicIndicators) {
|
||||||
|
magicIndicator.onPageSelected(pageIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dispatchPageScrollStateChanged(int state) {
|
||||||
|
for (MagicIndicator magicIndicator : mMagicIndicators) {
|
||||||
|
magicIndicator.onPageScrollStateChanged(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dispatchPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
for (MagicIndicator magicIndicator : mMagicIndicators) {
|
||||||
|
magicIndicator.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package net.lucode.hackware.magicindicator;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.abs.IPagerNavigator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 整个框架的入口,核心
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class MagicIndicator extends FrameLayout {
|
||||||
|
private IPagerNavigator mNavigator;
|
||||||
|
|
||||||
|
public MagicIndicator(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MagicIndicator(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
if (mNavigator != null) {
|
||||||
|
mNavigator.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
if (mNavigator != null) {
|
||||||
|
mNavigator.onPageSelected(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
if (mNavigator != null) {
|
||||||
|
mNavigator.onPageScrollStateChanged(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPagerNavigator getNavigator() {
|
||||||
|
return mNavigator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNavigator(IPagerNavigator navigator) {
|
||||||
|
if (mNavigator == navigator) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mNavigator != null) {
|
||||||
|
mNavigator.onDetachFromMagicIndicator();
|
||||||
|
}
|
||||||
|
mNavigator = navigator;
|
||||||
|
removeAllViews();
|
||||||
|
if (mNavigator instanceof View) {
|
||||||
|
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||||
|
addView((View) mNavigator, lp);
|
||||||
|
mNavigator.onAttachToMagicIndicator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
package net.lucode.hackware.magicindicator;
|
||||||
|
|
||||||
|
import android.util.SparseArray;
|
||||||
|
import android.util.SparseBooleanArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 方便扩展IPagerNavigator的帮助类,将ViewPager的3个回调方法转换成
|
||||||
|
* onSelected、onDeselected、onEnter等回调,方便扩展
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class NavigatorHelper {
|
||||||
|
private SparseBooleanArray mDeselectedItems = new SparseBooleanArray();
|
||||||
|
private SparseArray<Float> mLeavedPercents = new SparseArray<Float>();
|
||||||
|
|
||||||
|
private int mTotalCount;
|
||||||
|
private int mCurrentIndex;
|
||||||
|
private int mLastIndex;
|
||||||
|
private float mLastPositionOffsetSum;
|
||||||
|
private int mScrollState;
|
||||||
|
|
||||||
|
private boolean mSkimOver;
|
||||||
|
private NavigatorHelper.OnNavigatorScrollListener mNavigatorScrollListener;
|
||||||
|
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
float currentPositionOffsetSum = position + positionOffset;
|
||||||
|
boolean leftToRight = false;
|
||||||
|
if (mLastPositionOffsetSum <= currentPositionOffsetSum) {
|
||||||
|
leftToRight = true;
|
||||||
|
}
|
||||||
|
if (mScrollState != ScrollState.SCROLL_STATE_IDLE) {
|
||||||
|
if (currentPositionOffsetSum == mLastPositionOffsetSum) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int nextPosition = position + 1;
|
||||||
|
boolean normalDispatch = true;
|
||||||
|
if (positionOffset == 0.0f) {
|
||||||
|
if (leftToRight) {
|
||||||
|
nextPosition = position - 1;
|
||||||
|
normalDispatch = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < mTotalCount; i++) {
|
||||||
|
if (i == position || i == nextPosition) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Float leavedPercent = mLeavedPercents.get(i, 0.0f);
|
||||||
|
if (leavedPercent != 1.0f) {
|
||||||
|
dispatchOnLeave(i, 1.0f, leftToRight, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (normalDispatch) {
|
||||||
|
if (leftToRight) {
|
||||||
|
dispatchOnLeave(position, positionOffset, true, false);
|
||||||
|
dispatchOnEnter(nextPosition, positionOffset, true, false);
|
||||||
|
} else {
|
||||||
|
dispatchOnLeave(nextPosition, 1.0f - positionOffset, false, false);
|
||||||
|
dispatchOnEnter(position, 1.0f - positionOffset, false, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dispatchOnLeave(nextPosition, 1.0f - positionOffset, true, false);
|
||||||
|
dispatchOnEnter(position, 1.0f - positionOffset, true, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < mTotalCount; i++) {
|
||||||
|
if (i == mCurrentIndex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean deselected = mDeselectedItems.get(i);
|
||||||
|
if (!deselected) {
|
||||||
|
dispatchOnDeselected(i);
|
||||||
|
}
|
||||||
|
Float leavedPercent = mLeavedPercents.get(i, 0.0f);
|
||||||
|
if (leavedPercent != 1.0f) {
|
||||||
|
dispatchOnLeave(i, 1.0f, false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dispatchOnEnter(mCurrentIndex, 1.0f, false, true);
|
||||||
|
dispatchOnSelected(mCurrentIndex);
|
||||||
|
}
|
||||||
|
mLastPositionOffsetSum = currentPositionOffsetSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dispatchOnEnter(int index, float enterPercent, boolean leftToRight, boolean force) {
|
||||||
|
if (mSkimOver || index == mCurrentIndex || mScrollState == ScrollState.SCROLL_STATE_DRAGGING || force) {
|
||||||
|
if (mNavigatorScrollListener != null) {
|
||||||
|
mNavigatorScrollListener.onEnter(index, mTotalCount, enterPercent, leftToRight);
|
||||||
|
}
|
||||||
|
mLeavedPercents.put(index, 1.0f - enterPercent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dispatchOnLeave(int index, float leavePercent, boolean leftToRight, boolean force) {
|
||||||
|
if (mSkimOver || index == mLastIndex || mScrollState == ScrollState.SCROLL_STATE_DRAGGING || ((index == mCurrentIndex - 1 || index == mCurrentIndex + 1) && mLeavedPercents.get(index, 0.0f) != 1.0f) || force) {
|
||||||
|
if (mNavigatorScrollListener != null) {
|
||||||
|
mNavigatorScrollListener.onLeave(index, mTotalCount, leavePercent, leftToRight);
|
||||||
|
}
|
||||||
|
mLeavedPercents.put(index, leavePercent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dispatchOnSelected(int index) {
|
||||||
|
if (mNavigatorScrollListener != null) {
|
||||||
|
mNavigatorScrollListener.onSelected(index, mTotalCount);
|
||||||
|
}
|
||||||
|
mDeselectedItems.put(index, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dispatchOnDeselected(int index) {
|
||||||
|
if (mNavigatorScrollListener != null) {
|
||||||
|
mNavigatorScrollListener.onDeselected(index, mTotalCount);
|
||||||
|
}
|
||||||
|
mDeselectedItems.put(index, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
mLastIndex = mCurrentIndex;
|
||||||
|
mCurrentIndex = position;
|
||||||
|
dispatchOnSelected(mCurrentIndex);
|
||||||
|
for (int i = 0; i < mTotalCount; i++) {
|
||||||
|
if (i == mCurrentIndex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean deselected = mDeselectedItems.get(i);
|
||||||
|
if (!deselected) {
|
||||||
|
dispatchOnDeselected(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
mScrollState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNavigatorScrollListener(NavigatorHelper.OnNavigatorScrollListener navigatorScrollListener) {
|
||||||
|
mNavigatorScrollListener = navigatorScrollListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkimOver(boolean skimOver) {
|
||||||
|
mSkimOver = skimOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalCount() {
|
||||||
|
return mTotalCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalCount(int totalCount) {
|
||||||
|
mTotalCount = totalCount;
|
||||||
|
mDeselectedItems.clear();
|
||||||
|
mLeavedPercents.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurrentIndex() {
|
||||||
|
return mCurrentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScrollState() {
|
||||||
|
return mScrollState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnNavigatorScrollListener {
|
||||||
|
void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight);
|
||||||
|
|
||||||
|
void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight);
|
||||||
|
|
||||||
|
void onSelected(int index, int totalCount);
|
||||||
|
|
||||||
|
void onDeselected(int index, int totalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package net.lucode.hackware.magicindicator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义滚动状态,消除对ViewPager的依赖
|
||||||
|
* Created by hackware on 2016/8/27.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface ScrollState {
|
||||||
|
int SCROLL_STATE_IDLE = 0;
|
||||||
|
int SCROLL_STATE_DRAGGING = 1;
|
||||||
|
int SCROLL_STATE_SETTLING = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package net.lucode.hackware.magicindicator;
|
||||||
|
|
||||||
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简化和ViewPager绑定
|
||||||
|
* Created by hackware on 2016/8/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ViewPagerHelper {
|
||||||
|
public static void bind(final MagicIndicator magicIndicator, ViewPager viewPager) {
|
||||||
|
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
magicIndicator.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
magicIndicator.onPageSelected(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
magicIndicator.onPageScrollStateChanged(state);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.abs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽象的ViewPager导航器
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public interface IPagerNavigator {
|
||||||
|
|
||||||
|
///////////////////////// ViewPager的3个回调
|
||||||
|
void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
|
||||||
|
|
||||||
|
void onPageSelected(int position);
|
||||||
|
|
||||||
|
void onPageScrollStateChanged(int state);
|
||||||
|
/////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当IPagerNavigator被添加到MagicIndicator时调用
|
||||||
|
*/
|
||||||
|
void onAttachToMagicIndicator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当IPagerNavigator从MagicIndicator上移除时调用
|
||||||
|
*/
|
||||||
|
void onDetachFromMagicIndicator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ViewPager内容改变时需要先调用此方法,自定义的IPagerNavigator应当遵守此约定
|
||||||
|
*/
|
||||||
|
void notifyDataSetChanged();
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实现颜色渐变,考虑到兼容性,不使用内置的ArgbEvaluator
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class ArgbEvaluatorHolder {
|
||||||
|
public static int eval(float fraction, int startValue, int endValue) {
|
||||||
|
int startA = (startValue >> 24) & 0xff;
|
||||||
|
int startR = (startValue >> 16) & 0xff;
|
||||||
|
int startG = (startValue >> 8) & 0xff;
|
||||||
|
int startB = startValue & 0xff;
|
||||||
|
|
||||||
|
int endA = (endValue >> 24) & 0xff;
|
||||||
|
int endR = (endValue >> 16) & 0xff;
|
||||||
|
int endG = (endValue >> 8) & 0xff;
|
||||||
|
int endB = endValue & 0xff;
|
||||||
|
|
||||||
|
int currentA = (startA + (int) (fraction * (endA - startA))) << 24;
|
||||||
|
int currentR = (startR + (int) (fraction * (endR - startR))) << 16;
|
||||||
|
int currentG = (startG + (int) (fraction * (endG - startG))) << 8;
|
||||||
|
int currentB = startB + (int) (fraction * (endB - startB));
|
||||||
|
|
||||||
|
return currentA | currentR | currentG | currentB;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public final class UIUtil {
|
||||||
|
|
||||||
|
public static int dip2px(Context context, double dpValue) {
|
||||||
|
float density = context.getResources().getDisplayMetrics().density;
|
||||||
|
return (int) (dpValue * density + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getScreenWidth(Context context) {
|
||||||
|
return context.getResources().getDisplayMetrics().widthPixels;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,309 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.circlenavigator;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PointF;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewConfiguration;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.abs.IPagerNavigator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.UIUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 圆圈式的指示器
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class CircleNavigator extends View implements IPagerNavigator {
|
||||||
|
private int mRadius;
|
||||||
|
private int mCircleColor;
|
||||||
|
private int mStrokeWidth;
|
||||||
|
private int mCircleSpacing;
|
||||||
|
private int mCurrentIndex;
|
||||||
|
private int mTotalCount;
|
||||||
|
private Interpolator mStartInterpolator = new LinearInterpolator();
|
||||||
|
|
||||||
|
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
private List<PointF> mCirclePoints = new ArrayList<PointF>();
|
||||||
|
private float mIndicatorX;
|
||||||
|
|
||||||
|
// 事件回调
|
||||||
|
private boolean mTouchable;
|
||||||
|
private OnCircleClickListener mCircleClickListener;
|
||||||
|
private float mDownX;
|
||||||
|
private float mDownY;
|
||||||
|
private int mTouchSlop;
|
||||||
|
|
||||||
|
private boolean mFollowTouch = true; // 是否跟随手指滑动
|
||||||
|
|
||||||
|
public CircleNavigator(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||||
|
mRadius = UIUtil.dip2px(context, 3);
|
||||||
|
mCircleSpacing = UIUtil.dip2px(context, 8);
|
||||||
|
mStrokeWidth = UIUtil.dip2px(context, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int measureWidth(int widthMeasureSpec) {
|
||||||
|
int mode = MeasureSpec.getMode(widthMeasureSpec);
|
||||||
|
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
|
int result = 0;
|
||||||
|
switch (mode) {
|
||||||
|
case MeasureSpec.EXACTLY:
|
||||||
|
result = width;
|
||||||
|
break;
|
||||||
|
case MeasureSpec.AT_MOST:
|
||||||
|
case MeasureSpec.UNSPECIFIED:
|
||||||
|
result = mTotalCount * mRadius * 2 + (mTotalCount - 1) * mCircleSpacing + getPaddingLeft() + getPaddingRight() + mStrokeWidth * 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int measureHeight(int heightMeasureSpec) {
|
||||||
|
int mode = MeasureSpec.getMode(heightMeasureSpec);
|
||||||
|
int height = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
int result = 0;
|
||||||
|
switch (mode) {
|
||||||
|
case MeasureSpec.EXACTLY:
|
||||||
|
result = height;
|
||||||
|
break;
|
||||||
|
case MeasureSpec.AT_MOST:
|
||||||
|
case MeasureSpec.UNSPECIFIED:
|
||||||
|
result = mRadius * 2 + mStrokeWidth * 2 + getPaddingTop() + getPaddingBottom();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
mPaint.setColor(mCircleColor);
|
||||||
|
drawCircles(canvas);
|
||||||
|
drawIndicator(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawCircles(Canvas canvas) {
|
||||||
|
mPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
mPaint.setStrokeWidth(mStrokeWidth);
|
||||||
|
for (int i = 0, j = mCirclePoints.size(); i < j; i++) {
|
||||||
|
PointF pointF = mCirclePoints.get(i);
|
||||||
|
canvas.drawCircle(pointF.x, pointF.y, mRadius, mPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawIndicator(Canvas canvas) {
|
||||||
|
mPaint.setStyle(Paint.Style.FILL);
|
||||||
|
if (mCirclePoints.size() > 0) {
|
||||||
|
canvas.drawCircle(mIndicatorX, (int) (getHeight() / 2.0f + 0.5f), mRadius, mPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareCirclePoints() {
|
||||||
|
mCirclePoints.clear();
|
||||||
|
if (mTotalCount > 0) {
|
||||||
|
int y = (int) (getHeight() / 2.0f + 0.5f);
|
||||||
|
int centerSpacing = mRadius * 2 + mCircleSpacing;
|
||||||
|
int startX = mRadius + (int) (mStrokeWidth / 2.0f + 0.5f) + getPaddingLeft();
|
||||||
|
for (int i = 0; i < mTotalCount; i++) {
|
||||||
|
PointF pointF = new PointF(startX, y);
|
||||||
|
mCirclePoints.add(pointF);
|
||||||
|
startX += centerSpacing;
|
||||||
|
}
|
||||||
|
mIndicatorX = mCirclePoints.get(mCurrentIndex).x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
if (mFollowTouch) {
|
||||||
|
if (mCirclePoints.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int currentPosition = Math.min(mCirclePoints.size() - 1, position);
|
||||||
|
int nextPosition = Math.min(mCirclePoints.size() - 1, position + 1);
|
||||||
|
PointF current = mCirclePoints.get(currentPosition);
|
||||||
|
PointF next = mCirclePoints.get(nextPosition);
|
||||||
|
|
||||||
|
mIndicatorX = current.x + (next.x - current.x) * mStartInterpolator.getInterpolation(positionOffset);
|
||||||
|
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
float x = event.getX();
|
||||||
|
float y = event.getY();
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
if (mTouchable) {
|
||||||
|
mDownX = x;
|
||||||
|
mDownY = y;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
if (mCircleClickListener != null) {
|
||||||
|
if (Math.abs(x - mDownX) <= mTouchSlop && Math.abs(y - mDownY) <= mTouchSlop) {
|
||||||
|
float max = Float.MAX_VALUE;
|
||||||
|
int index = 0;
|
||||||
|
for (int i = 0; i < mCirclePoints.size(); i++) {
|
||||||
|
PointF pointF = mCirclePoints.get(i);
|
||||||
|
float offset = Math.abs(pointF.x - x);
|
||||||
|
if (offset < max) {
|
||||||
|
max = offset;
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mCircleClickListener.onClick(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
mCurrentIndex = position;
|
||||||
|
if (!mFollowTouch) {
|
||||||
|
mIndicatorX = mCirclePoints.get(mCurrentIndex).x;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||||
|
prepareCirclePoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachToMagicIndicator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyDataSetChanged() {
|
||||||
|
prepareCirclePoints();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetachFromMagicIndicator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRadius() {
|
||||||
|
return mRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRadius(int radius) {
|
||||||
|
mRadius = radius;
|
||||||
|
prepareCirclePoints();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCircleColor() {
|
||||||
|
return mCircleColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCircleColor(int circleColor) {
|
||||||
|
mCircleColor = circleColor;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStrokeWidth() {
|
||||||
|
return mStrokeWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStrokeWidth(int strokeWidth) {
|
||||||
|
mStrokeWidth = strokeWidth;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCircleSpacing() {
|
||||||
|
return mCircleSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCircleSpacing(int circleSpacing) {
|
||||||
|
mCircleSpacing = circleSpacing;
|
||||||
|
prepareCirclePoints();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Interpolator getStartInterpolator() {
|
||||||
|
return mStartInterpolator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartInterpolator(Interpolator startInterpolator) {
|
||||||
|
mStartInterpolator = startInterpolator;
|
||||||
|
if (mStartInterpolator == null) {
|
||||||
|
mStartInterpolator = new LinearInterpolator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCircleCount() {
|
||||||
|
return mTotalCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCircleCount(int count) {
|
||||||
|
mTotalCount = count; // 此处不调用invalidate,让外部调用notifyDataSetChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTouchable() {
|
||||||
|
return mTouchable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTouchable(boolean touchable) {
|
||||||
|
mTouchable = touchable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFollowTouch() {
|
||||||
|
return mFollowTouch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFollowTouch(boolean followTouch) {
|
||||||
|
mFollowTouch = followTouch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnCircleClickListener getCircleClickListener() {
|
||||||
|
return mCircleClickListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCircleClickListener(OnCircleClickListener circleClickListener) {
|
||||||
|
if (!mTouchable) {
|
||||||
|
mTouchable = true;
|
||||||
|
}
|
||||||
|
mCircleClickListener = circleClickListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnCircleClickListener {
|
||||||
|
void onClick(int index);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,425 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.DataSetObserver;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.HorizontalScrollView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.NavigatorHelper;
|
||||||
|
import net.lucode.hackware.magicindicator.R;
|
||||||
|
import net.lucode.hackware.magicindicator.ScrollState;
|
||||||
|
import net.lucode.hackware.magicindicator.abs.IPagerNavigator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.CommonNavigatorAdapter;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IMeasurablePagerTitleView;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerTitleView;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.model.PositionData;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用的ViewPager指示器,包含PagerTitle和PagerIndicator
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class CommonNavigator extends FrameLayout implements IPagerNavigator, NavigatorHelper.OnNavigatorScrollListener {
|
||||||
|
private HorizontalScrollView mScrollView;
|
||||||
|
private LinearLayout mTitleContainer;
|
||||||
|
private LinearLayout mIndicatorContainer;
|
||||||
|
private IPagerIndicator mIndicator;
|
||||||
|
|
||||||
|
private CommonNavigatorAdapter mAdapter;
|
||||||
|
private NavigatorHelper mNavigatorHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提供给外部的参数配置
|
||||||
|
*/
|
||||||
|
/****************************************************/
|
||||||
|
private boolean mAdjustMode; // 自适应模式,适用于数目固定的、少量的title
|
||||||
|
private boolean mEnablePivotScroll; // 启动中心点滚动
|
||||||
|
private float mScrollPivotX = 0.5f; // 滚动中心点 0.0f - 1.0f
|
||||||
|
private boolean mSmoothScroll = true; // 是否平滑滚动,适用于 !mAdjustMode && !mFollowTouch
|
||||||
|
private boolean mFollowTouch = true; // 是否手指跟随滚动
|
||||||
|
private int mRightPadding;
|
||||||
|
private int mLeftPadding;
|
||||||
|
private boolean mIndicatorOnTop; // 指示器是否在title上层,默认为下层
|
||||||
|
private boolean mSkimOver; // 跨多页切换时,中间页是否显示 "掠过" 效果
|
||||||
|
private boolean mReselectWhenLayout = true; // PositionData准备好时,是否重新选中当前页,为true可保证在极端情况下指示器状态正确
|
||||||
|
/****************************************************/
|
||||||
|
|
||||||
|
// 保存每个title的位置信息,为扩展indicator提供保障
|
||||||
|
private List<PositionData> mPositionDataList = new ArrayList<PositionData>();
|
||||||
|
|
||||||
|
private DataSetObserver mObserver = new DataSetObserver() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChanged() {
|
||||||
|
mNavigatorHelper.setTotalCount(mAdapter.getCount()); // 如果使用helper,应始终保证helper中的totalCount为最新
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInvalidated() {
|
||||||
|
// 没什么用,暂不做处理
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public CommonNavigator(Context context) {
|
||||||
|
super(context);
|
||||||
|
mNavigatorHelper = new NavigatorHelper();
|
||||||
|
mNavigatorHelper.setNavigatorScrollListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyDataSetChanged() {
|
||||||
|
if (mAdapter != null) {
|
||||||
|
mAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAdjustMode() {
|
||||||
|
return mAdjustMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAdjustMode(boolean is) {
|
||||||
|
mAdjustMode = is;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommonNavigatorAdapter getAdapter() {
|
||||||
|
return mAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAdapter(CommonNavigatorAdapter adapter) {
|
||||||
|
if (mAdapter == adapter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mAdapter != null) {
|
||||||
|
mAdapter.unregisterDataSetObserver(mObserver);
|
||||||
|
}
|
||||||
|
mAdapter = adapter;
|
||||||
|
if (mAdapter != null) {
|
||||||
|
mAdapter.registerDataSetObserver(mObserver);
|
||||||
|
mNavigatorHelper.setTotalCount(mAdapter.getCount());
|
||||||
|
if (mTitleContainer != null) { // adapter改变时,应该重新init,但是第一次设置adapter不用,onAttachToMagicIndicator中有init
|
||||||
|
mAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mNavigatorHelper.setTotalCount(0);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
removeAllViews();
|
||||||
|
|
||||||
|
View root;
|
||||||
|
if (mAdjustMode) {
|
||||||
|
root = LayoutInflater.from(getContext()).inflate(R.layout.pager_navigator_layout_no_scroll, this);
|
||||||
|
} else {
|
||||||
|
root = LayoutInflater.from(getContext()).inflate(R.layout.pager_navigator_layout, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
mScrollView = (HorizontalScrollView) root.findViewById(R.id.scroll_view); // mAdjustMode为true时,mScrollView为null
|
||||||
|
|
||||||
|
mTitleContainer = (LinearLayout) root.findViewById(R.id.title_container);
|
||||||
|
mTitleContainer.setPadding(mLeftPadding, 0, mRightPadding, 0);
|
||||||
|
|
||||||
|
mIndicatorContainer = (LinearLayout) root.findViewById(R.id.indicator_container);
|
||||||
|
if (mIndicatorOnTop) {
|
||||||
|
mIndicatorContainer.getParent().bringChildToFront(mIndicatorContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
initTitlesAndIndicator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化title和indicator
|
||||||
|
*/
|
||||||
|
private void initTitlesAndIndicator() {
|
||||||
|
for (int i = 0, j = mNavigatorHelper.getTotalCount(); i < j; i++) {
|
||||||
|
IPagerTitleView v = mAdapter.getTitleView(getContext(), i);
|
||||||
|
if (v instanceof View) {
|
||||||
|
View view = (View) v;
|
||||||
|
LinearLayout.LayoutParams lp;
|
||||||
|
if (mAdjustMode) {
|
||||||
|
lp = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
lp.weight = mAdapter.getTitleWeight(getContext(), i);
|
||||||
|
} else {
|
||||||
|
lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
||||||
|
}
|
||||||
|
mTitleContainer.addView(view, lp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mAdapter != null) {
|
||||||
|
mIndicator = mAdapter.getIndicator(getContext());
|
||||||
|
if (mIndicator instanceof View) {
|
||||||
|
LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
mIndicatorContainer.addView((View) mIndicator, lp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||||
|
super.onLayout(changed, left, top, right, bottom);
|
||||||
|
if (mAdapter != null) {
|
||||||
|
preparePositionData();
|
||||||
|
if (mIndicator != null) {
|
||||||
|
mIndicator.onPositionDataProvide(mPositionDataList);
|
||||||
|
}
|
||||||
|
if (mReselectWhenLayout && mNavigatorHelper.getScrollState() == ScrollState.SCROLL_STATE_IDLE) {
|
||||||
|
onPageSelected(mNavigatorHelper.getCurrentIndex());
|
||||||
|
onPageScrolled(mNavigatorHelper.getCurrentIndex(), 0.0f, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取title的位置信息,为打造不同的指示器、各种效果提供可能
|
||||||
|
*/
|
||||||
|
private void preparePositionData() {
|
||||||
|
mPositionDataList.clear();
|
||||||
|
for (int i = 0, j = mNavigatorHelper.getTotalCount(); i < j; i++) {
|
||||||
|
PositionData data = new PositionData();
|
||||||
|
View v = mTitleContainer.getChildAt(i);
|
||||||
|
if (v != null) {
|
||||||
|
data.mLeft = v.getLeft();
|
||||||
|
data.mTop = v.getTop();
|
||||||
|
data.mRight = v.getRight();
|
||||||
|
data.mBottom = v.getBottom();
|
||||||
|
if (v instanceof IMeasurablePagerTitleView) {
|
||||||
|
IMeasurablePagerTitleView view = (IMeasurablePagerTitleView) v;
|
||||||
|
data.mContentLeft = view.getContentLeft();
|
||||||
|
data.mContentTop = view.getContentTop();
|
||||||
|
data.mContentRight = view.getContentRight();
|
||||||
|
data.mContentBottom = view.getContentBottom();
|
||||||
|
} else {
|
||||||
|
data.mContentLeft = data.mLeft;
|
||||||
|
data.mContentTop = data.mTop;
|
||||||
|
data.mContentRight = data.mRight;
|
||||||
|
data.mContentBottom = data.mBottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mPositionDataList.add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
if (mAdapter != null) {
|
||||||
|
|
||||||
|
mNavigatorHelper.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||||
|
if (mIndicator != null) {
|
||||||
|
mIndicator.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手指跟随滚动
|
||||||
|
if (mScrollView != null && mPositionDataList.size() > 0 && position >= 0 && position < mPositionDataList.size()) {
|
||||||
|
if (mFollowTouch) {
|
||||||
|
int currentPosition = Math.min(mPositionDataList.size() - 1, position);
|
||||||
|
int nextPosition = Math.min(mPositionDataList.size() - 1, position + 1);
|
||||||
|
PositionData current = mPositionDataList.get(currentPosition);
|
||||||
|
PositionData next = mPositionDataList.get(nextPosition);
|
||||||
|
float scrollTo = current.horizontalCenter() - mScrollView.getWidth() * mScrollPivotX;
|
||||||
|
float nextScrollTo = next.horizontalCenter() - mScrollView.getWidth() * mScrollPivotX;
|
||||||
|
mScrollView.scrollTo((int) (scrollTo + (nextScrollTo - scrollTo) * positionOffset), 0);
|
||||||
|
} else if (!mEnablePivotScroll) {
|
||||||
|
// TODO 实现待选中项完全显示出来
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getScrollPivotX() {
|
||||||
|
return mScrollPivotX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScrollPivotX(float scrollPivotX) {
|
||||||
|
mScrollPivotX = scrollPivotX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
if (mAdapter != null) {
|
||||||
|
mNavigatorHelper.onPageSelected(position);
|
||||||
|
if (mIndicator != null) {
|
||||||
|
mIndicator.onPageSelected(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
if (mAdapter != null) {
|
||||||
|
mNavigatorHelper.onPageScrollStateChanged(state);
|
||||||
|
if (mIndicator != null) {
|
||||||
|
mIndicator.onPageScrollStateChanged(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachToMagicIndicator() {
|
||||||
|
init(); // 将初始化延迟到这里
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetachFromMagicIndicator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPagerIndicator getPagerIndicator() {
|
||||||
|
return mIndicator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnablePivotScroll() {
|
||||||
|
return mEnablePivotScroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnablePivotScroll(boolean is) {
|
||||||
|
mEnablePivotScroll = is;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {
|
||||||
|
if (mTitleContainer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
View v = mTitleContainer.getChildAt(index);
|
||||||
|
if (v instanceof IPagerTitleView) {
|
||||||
|
((IPagerTitleView) v).onEnter(index, totalCount, enterPercent, leftToRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {
|
||||||
|
if (mTitleContainer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
View v = mTitleContainer.getChildAt(index);
|
||||||
|
if (v instanceof IPagerTitleView) {
|
||||||
|
((IPagerTitleView) v).onLeave(index, totalCount, leavePercent, leftToRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSmoothScroll() {
|
||||||
|
return mSmoothScroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmoothScroll(boolean smoothScroll) {
|
||||||
|
mSmoothScroll = smoothScroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFollowTouch() {
|
||||||
|
return mFollowTouch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFollowTouch(boolean followTouch) {
|
||||||
|
mFollowTouch = followTouch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSkimOver() {
|
||||||
|
return mSkimOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkimOver(boolean skimOver) {
|
||||||
|
mSkimOver = skimOver;
|
||||||
|
mNavigatorHelper.setSkimOver(skimOver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSelected(int index, int totalCount) {
|
||||||
|
if (mTitleContainer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
View v = mTitleContainer.getChildAt(index);
|
||||||
|
if (v instanceof IPagerTitleView) {
|
||||||
|
((IPagerTitleView) v).onSelected(index, totalCount);
|
||||||
|
}
|
||||||
|
if (!mAdjustMode && !mFollowTouch && mScrollView != null && mPositionDataList.size() > 0) {
|
||||||
|
int currentIndex = Math.min(mPositionDataList.size() - 1, index);
|
||||||
|
PositionData current = mPositionDataList.get(currentIndex);
|
||||||
|
if (mEnablePivotScroll) {
|
||||||
|
float scrollTo = current.horizontalCenter() - mScrollView.getWidth() * mScrollPivotX;
|
||||||
|
if (mSmoothScroll) {
|
||||||
|
mScrollView.smoothScrollTo((int) (scrollTo), 0);
|
||||||
|
} else {
|
||||||
|
mScrollView.scrollTo((int) (scrollTo), 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果当前项被部分遮挡,则滚动显示完全
|
||||||
|
if (mScrollView.getScrollX() > current.mLeft) {
|
||||||
|
if (mSmoothScroll) {
|
||||||
|
mScrollView.smoothScrollTo(current.mLeft, 0);
|
||||||
|
} else {
|
||||||
|
mScrollView.scrollTo(current.mLeft, 0);
|
||||||
|
}
|
||||||
|
} else if (mScrollView.getScrollX() + getWidth() < current.mRight) {
|
||||||
|
if (mSmoothScroll) {
|
||||||
|
mScrollView.smoothScrollTo(current.mRight - getWidth(), 0);
|
||||||
|
} else {
|
||||||
|
mScrollView.scrollTo(current.mRight - getWidth(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeselected(int index, int totalCount) {
|
||||||
|
if (mTitleContainer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
View v = mTitleContainer.getChildAt(index);
|
||||||
|
if (v instanceof IPagerTitleView) {
|
||||||
|
((IPagerTitleView) v).onDeselected(index, totalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPagerTitleView getPagerTitleView(int index) {
|
||||||
|
if (mTitleContainer == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (IPagerTitleView) mTitleContainer.getChildAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinearLayout getTitleContainer() {
|
||||||
|
return mTitleContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRightPadding() {
|
||||||
|
return mRightPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRightPadding(int rightPadding) {
|
||||||
|
mRightPadding = rightPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLeftPadding() {
|
||||||
|
return mLeftPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeftPadding(int leftPadding) {
|
||||||
|
mLeftPadding = leftPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isIndicatorOnTop() {
|
||||||
|
return mIndicatorOnTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndicatorOnTop(boolean indicatorOnTop) {
|
||||||
|
mIndicatorOnTop = indicatorOnTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReselectWhenLayout() {
|
||||||
|
return mReselectWhenLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReselectWhenLayout(boolean reselectWhenLayout) {
|
||||||
|
mReselectWhenLayout = reselectWhenLayout;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.abs;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.DataSetObservable;
|
||||||
|
import android.database.DataSetObserver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CommonNavigator适配器,通过它可轻松切换不同的指示器样式
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public abstract class CommonNavigatorAdapter {
|
||||||
|
|
||||||
|
private final DataSetObservable mDataSetObservable = new DataSetObservable();
|
||||||
|
|
||||||
|
public abstract int getCount();
|
||||||
|
|
||||||
|
public abstract IPagerTitleView getTitleView(Context context, int index);
|
||||||
|
|
||||||
|
public abstract IPagerIndicator getIndicator(Context context);
|
||||||
|
|
||||||
|
public float getTitleWeight(Context context, int index) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void registerDataSetObserver(DataSetObserver observer) {
|
||||||
|
mDataSetObservable.registerObserver(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void unregisterDataSetObserver(DataSetObserver observer) {
|
||||||
|
mDataSetObservable.unregisterObserver(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void notifyDataSetChanged() {
|
||||||
|
mDataSetObservable.notifyChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void notifyDataSetInvalidated() {
|
||||||
|
mDataSetObservable.notifyInvalidated();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.abs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可测量内容区域的指示器标题
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public interface IMeasurablePagerTitleView extends IPagerTitleView {
|
||||||
|
int getContentLeft();
|
||||||
|
|
||||||
|
int getContentTop();
|
||||||
|
|
||||||
|
int getContentRight();
|
||||||
|
|
||||||
|
int getContentBottom();
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.abs;
|
||||||
|
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.model.PositionData;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽象的viewpager指示器,适用于CommonNavigator
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public interface IPagerIndicator {
|
||||||
|
void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
|
||||||
|
|
||||||
|
void onPageSelected(int position);
|
||||||
|
|
||||||
|
void onPageScrollStateChanged(int state);
|
||||||
|
|
||||||
|
void onPositionDataProvide(List<PositionData> dataList);
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.abs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽象的指示器标题,适用于CommonNavigator
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public interface IPagerTitleView {
|
||||||
|
/**
|
||||||
|
* 被选中
|
||||||
|
*/
|
||||||
|
void onSelected(int index, int totalCount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未被选中
|
||||||
|
*/
|
||||||
|
void onDeselected(int index, int totalCount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 离开
|
||||||
|
*
|
||||||
|
* @param leavePercent 离开的百分比, 0.0f - 1.0f
|
||||||
|
* @param leftToRight 从左至右离开
|
||||||
|
*/
|
||||||
|
void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进入
|
||||||
|
*
|
||||||
|
* @param enterPercent 进入的百分比, 0.0f - 1.0f
|
||||||
|
* @param leftToRight 从左至右离开
|
||||||
|
*/
|
||||||
|
void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight);
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.AccelerateInterpolator;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.FragmentContainerHelper;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.ArgbEvaluatorHolder;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.UIUtil;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.model.PositionData;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 贝塞尔曲线ViewPager指示器,带颜色渐变
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class BezierPagerIndicator extends View implements IPagerIndicator {
|
||||||
|
private List<PositionData> mPositionDataList;
|
||||||
|
|
||||||
|
private float mLeftCircleRadius;
|
||||||
|
private float mLeftCircleX;
|
||||||
|
private float mRightCircleRadius;
|
||||||
|
private float mRightCircleX;
|
||||||
|
|
||||||
|
private float mYOffset;
|
||||||
|
private float mMaxCircleRadius;
|
||||||
|
private float mMinCircleRadius;
|
||||||
|
|
||||||
|
private Paint mPaint;
|
||||||
|
private Path mPath = new Path();
|
||||||
|
|
||||||
|
private List<Integer> mColors;
|
||||||
|
private Interpolator mStartInterpolator = new AccelerateInterpolator();
|
||||||
|
private Interpolator mEndInterpolator = new DecelerateInterpolator();
|
||||||
|
|
||||||
|
public BezierPagerIndicator(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mMaxCircleRadius = UIUtil.dip2px(context, 3.5);
|
||||||
|
mMinCircleRadius = UIUtil.dip2px(context, 2);
|
||||||
|
mYOffset = UIUtil.dip2px(context, 1.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
canvas.drawCircle(mLeftCircleX, getHeight() - mYOffset - mMaxCircleRadius, mLeftCircleRadius, mPaint);
|
||||||
|
canvas.drawCircle(mRightCircleX, getHeight() - mYOffset - mMaxCircleRadius, mRightCircleRadius, mPaint);
|
||||||
|
drawBezierCurve(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制贝塞尔曲线
|
||||||
|
*
|
||||||
|
* @param canvas
|
||||||
|
*/
|
||||||
|
private void drawBezierCurve(Canvas canvas) {
|
||||||
|
mPath.reset();
|
||||||
|
float y = getHeight() - mYOffset - mMaxCircleRadius;
|
||||||
|
mPath.moveTo(mRightCircleX, y);
|
||||||
|
mPath.lineTo(mRightCircleX, y - mRightCircleRadius);
|
||||||
|
mPath.quadTo(mRightCircleX + (mLeftCircleX - mRightCircleX) / 2.0f, y, mLeftCircleX, y - mLeftCircleRadius);
|
||||||
|
mPath.lineTo(mLeftCircleX, y + mLeftCircleRadius);
|
||||||
|
mPath.quadTo(mRightCircleX + (mLeftCircleX - mRightCircleX) / 2.0f, y, mRightCircleX, y + mRightCircleRadius);
|
||||||
|
mPath.close(); // 闭合
|
||||||
|
canvas.drawPath(mPath, mPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
if (mPositionDataList == null || mPositionDataList.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算颜色
|
||||||
|
if (mColors != null && mColors.size() > 0) {
|
||||||
|
int currentColor = mColors.get(Math.abs(position) % mColors.size());
|
||||||
|
int nextColor = mColors.get(Math.abs(position + 1) % mColors.size());
|
||||||
|
int color = ArgbEvaluatorHolder.eval(positionOffset, currentColor, nextColor);
|
||||||
|
mPaint.setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算锚点位置
|
||||||
|
PositionData current = FragmentContainerHelper.getImitativePositionData(mPositionDataList, position);
|
||||||
|
PositionData next = FragmentContainerHelper.getImitativePositionData(mPositionDataList, position + 1);
|
||||||
|
|
||||||
|
float leftX = current.mLeft + (current.mRight - current.mLeft) / 2;
|
||||||
|
float rightX = next.mLeft + (next.mRight - next.mLeft) / 2;
|
||||||
|
|
||||||
|
mLeftCircleX = leftX + (rightX - leftX) * mStartInterpolator.getInterpolation(positionOffset);
|
||||||
|
mRightCircleX = leftX + (rightX - leftX) * mEndInterpolator.getInterpolation(positionOffset);
|
||||||
|
mLeftCircleRadius = mMaxCircleRadius + (mMinCircleRadius - mMaxCircleRadius) * mEndInterpolator.getInterpolation(positionOffset);
|
||||||
|
mRightCircleRadius = mMinCircleRadius + (mMaxCircleRadius - mMinCircleRadius) * mStartInterpolator.getInterpolation(positionOffset);
|
||||||
|
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPositionDataProvide(List<PositionData> dataList) {
|
||||||
|
mPositionDataList = dataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMaxCircleRadius() {
|
||||||
|
return mMaxCircleRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxCircleRadius(float maxCircleRadius) {
|
||||||
|
mMaxCircleRadius = maxCircleRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMinCircleRadius() {
|
||||||
|
return mMinCircleRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinCircleRadius(float minCircleRadius) {
|
||||||
|
mMinCircleRadius = minCircleRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getYOffset() {
|
||||||
|
return mYOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYOffset(float yOffset) {
|
||||||
|
mYOffset = yOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColors(Integer... colors) {
|
||||||
|
mColors = Arrays.asList(colors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartInterpolator(Interpolator startInterpolator) {
|
||||||
|
mStartInterpolator = startInterpolator;
|
||||||
|
if (mStartInterpolator == null) {
|
||||||
|
mStartInterpolator = new AccelerateInterpolator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndInterpolator(Interpolator endInterpolator) {
|
||||||
|
mEndInterpolator = endInterpolator;
|
||||||
|
if (mEndInterpolator == null) {
|
||||||
|
mEndInterpolator = new DecelerateInterpolator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.FragmentContainerHelper;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.ArgbEvaluatorHolder;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.UIUtil;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.model.PositionData;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直线viewpager指示器,带颜色渐变
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class LinePagerIndicator extends View implements IPagerIndicator {
|
||||||
|
public static final int MODE_MATCH_EDGE = 0; // 直线宽度 == title宽度 - 2 * mXOffset
|
||||||
|
public static final int MODE_WRAP_CONTENT = 1; // 直线宽度 == title内容宽度 - 2 * mXOffset
|
||||||
|
public static final int MODE_EXACTLY = 2; // 直线宽度 == mLineWidth
|
||||||
|
|
||||||
|
private int mMode; // 默认为MODE_MATCH_EDGE模式
|
||||||
|
|
||||||
|
// 控制动画
|
||||||
|
private Interpolator mStartInterpolator = new LinearInterpolator();
|
||||||
|
private Interpolator mEndInterpolator = new LinearInterpolator();
|
||||||
|
|
||||||
|
private float mYOffset; // 相对于底部的偏移量,如果你想让直线位于title上方,设置它即可
|
||||||
|
private float mLineHeight;
|
||||||
|
private float mXOffset;
|
||||||
|
private float mLineWidth;
|
||||||
|
private float mRoundRadius;
|
||||||
|
|
||||||
|
private Paint mPaint;
|
||||||
|
private List<PositionData> mPositionDataList;
|
||||||
|
private List<Integer> mColors;
|
||||||
|
|
||||||
|
private RectF mLineRect = new RectF();
|
||||||
|
|
||||||
|
public LinePagerIndicator(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mLineHeight = UIUtil.dip2px(context, 3);
|
||||||
|
mLineWidth = UIUtil.dip2px(context, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
canvas.drawRoundRect(mLineRect, mRoundRadius, mRoundRadius, mPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
if (mPositionDataList == null || mPositionDataList.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算颜色
|
||||||
|
if (mColors != null && mColors.size() > 0) {
|
||||||
|
int currentColor = mColors.get(Math.abs(position) % mColors.size());
|
||||||
|
int nextColor = mColors.get(Math.abs(position + 1) % mColors.size());
|
||||||
|
int color = ArgbEvaluatorHolder.eval(positionOffset, currentColor, nextColor);
|
||||||
|
mPaint.setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算锚点位置
|
||||||
|
PositionData current = FragmentContainerHelper.getImitativePositionData(mPositionDataList, position);
|
||||||
|
PositionData next = FragmentContainerHelper.getImitativePositionData(mPositionDataList, position + 1);
|
||||||
|
|
||||||
|
float leftX;
|
||||||
|
float nextLeftX;
|
||||||
|
float rightX;
|
||||||
|
float nextRightX;
|
||||||
|
if (mMode == MODE_MATCH_EDGE) {
|
||||||
|
leftX = current.mLeft + mXOffset;
|
||||||
|
nextLeftX = next.mLeft + mXOffset;
|
||||||
|
rightX = current.mRight - mXOffset;
|
||||||
|
nextRightX = next.mRight - mXOffset;
|
||||||
|
} else if (mMode == MODE_WRAP_CONTENT) {
|
||||||
|
leftX = current.mContentLeft + mXOffset;
|
||||||
|
nextLeftX = next.mContentLeft + mXOffset;
|
||||||
|
rightX = current.mContentRight - mXOffset;
|
||||||
|
nextRightX = next.mContentRight - mXOffset;
|
||||||
|
} else { // MODE_EXACTLY
|
||||||
|
leftX = current.mLeft + (current.width() - mLineWidth) / 2;
|
||||||
|
nextLeftX = next.mLeft + (next.width() - mLineWidth) / 2;
|
||||||
|
rightX = current.mLeft + (current.width() + mLineWidth) / 2;
|
||||||
|
nextRightX = next.mLeft + (next.width() + mLineWidth) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLineRect.left = leftX + (nextLeftX - leftX) * mStartInterpolator.getInterpolation(positionOffset);
|
||||||
|
mLineRect.right = rightX + (nextRightX - rightX) * mEndInterpolator.getInterpolation(positionOffset);
|
||||||
|
mLineRect.top = getHeight() - mLineHeight - mYOffset;
|
||||||
|
mLineRect.bottom = getHeight() - mYOffset;
|
||||||
|
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPositionDataProvide(List<PositionData> dataList) {
|
||||||
|
mPositionDataList = dataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getYOffset() {
|
||||||
|
return mYOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYOffset(float yOffset) {
|
||||||
|
mYOffset = yOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getXOffset() {
|
||||||
|
return mXOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXOffset(float xOffset) {
|
||||||
|
mXOffset = xOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getLineHeight() {
|
||||||
|
return mLineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLineHeight(float lineHeight) {
|
||||||
|
mLineHeight = lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getLineWidth() {
|
||||||
|
return mLineWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLineWidth(float lineWidth) {
|
||||||
|
mLineWidth = lineWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getRoundRadius() {
|
||||||
|
return mRoundRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoundRadius(float roundRadius) {
|
||||||
|
mRoundRadius = roundRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMode() {
|
||||||
|
return mMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMode(int mode) {
|
||||||
|
if (mode == MODE_EXACTLY || mode == MODE_MATCH_EDGE || mode == MODE_WRAP_CONTENT) {
|
||||||
|
mMode = mode;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("mode " + mode + " not supported.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Paint getPaint() {
|
||||||
|
return mPaint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getColors() {
|
||||||
|
return mColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColors(Integer... colors) {
|
||||||
|
mColors = Arrays.asList(colors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Interpolator getStartInterpolator() {
|
||||||
|
return mStartInterpolator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartInterpolator(Interpolator startInterpolator) {
|
||||||
|
mStartInterpolator = startInterpolator;
|
||||||
|
if (mStartInterpolator == null) {
|
||||||
|
mStartInterpolator = new LinearInterpolator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Interpolator getEndInterpolator() {
|
||||||
|
return mEndInterpolator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndInterpolator(Interpolator endInterpolator) {
|
||||||
|
mEndInterpolator = endInterpolator;
|
||||||
|
if (mEndInterpolator == null) {
|
||||||
|
mEndInterpolator = new LinearInterpolator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.FragmentContainerHelper;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.model.PositionData;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于测试的指示器,可用来检测自定义的IMeasurablePagerTitleView是否正确测量内容区域
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class TestPagerIndicator extends View implements IPagerIndicator {
|
||||||
|
private Paint mPaint;
|
||||||
|
private int mOutRectColor;
|
||||||
|
private int mInnerRectColor;
|
||||||
|
private RectF mOutRect = new RectF();
|
||||||
|
private RectF mInnerRect = new RectF();
|
||||||
|
|
||||||
|
private List<PositionData> mPositionDataList;
|
||||||
|
|
||||||
|
public TestPagerIndicator(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
mOutRectColor = Color.RED;
|
||||||
|
mInnerRectColor = Color.GREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
mPaint.setColor(mOutRectColor);
|
||||||
|
canvas.drawRect(mOutRect, mPaint);
|
||||||
|
mPaint.setColor(mInnerRectColor);
|
||||||
|
canvas.drawRect(mInnerRect, mPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
if (mPositionDataList == null || mPositionDataList.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算锚点位置
|
||||||
|
PositionData current = FragmentContainerHelper.getImitativePositionData(mPositionDataList, position);
|
||||||
|
PositionData next = FragmentContainerHelper.getImitativePositionData(mPositionDataList, position + 1);
|
||||||
|
|
||||||
|
mOutRect.left = current.mLeft + (next.mLeft - current.mLeft) * positionOffset;
|
||||||
|
mOutRect.top = current.mTop + (next.mTop - current.mTop) * positionOffset;
|
||||||
|
mOutRect.right = current.mRight + (next.mRight - current.mRight) * positionOffset;
|
||||||
|
mOutRect.bottom = current.mBottom + (next.mBottom - current.mBottom) * positionOffset;
|
||||||
|
|
||||||
|
mInnerRect.left = current.mContentLeft + (next.mContentLeft - current.mContentLeft) * positionOffset;
|
||||||
|
mInnerRect.top = current.mContentTop + (next.mContentTop - current.mContentTop) * positionOffset;
|
||||||
|
mInnerRect.right = current.mContentRight + (next.mContentRight - current.mContentRight) * positionOffset;
|
||||||
|
mInnerRect.bottom = current.mContentBottom + (next.mContentBottom - current.mContentBottom) * positionOffset;
|
||||||
|
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPositionDataProvide(List<PositionData> dataList) {
|
||||||
|
mPositionDataList = dataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOutRectColor() {
|
||||||
|
return mOutRectColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutRectColor(int outRectColor) {
|
||||||
|
mOutRectColor = outRectColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInnerRectColor() {
|
||||||
|
return mInnerRectColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInnerRectColor(int innerRectColor) {
|
||||||
|
mInnerRectColor = innerRectColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.FragmentContainerHelper;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.UIUtil;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.model.PositionData;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 带有小尖角的直线指示器
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class TriangularPagerIndicator extends View implements IPagerIndicator {
|
||||||
|
private List<PositionData> mPositionDataList;
|
||||||
|
private Paint mPaint;
|
||||||
|
private int mLineHeight;
|
||||||
|
private int mLineColor;
|
||||||
|
private int mTriangleHeight;
|
||||||
|
private int mTriangleWidth;
|
||||||
|
private boolean mReverse;
|
||||||
|
private float mYOffset;
|
||||||
|
|
||||||
|
private Path mPath = new Path();
|
||||||
|
private Interpolator mStartInterpolator = new LinearInterpolator();
|
||||||
|
private float mAnchorX;
|
||||||
|
|
||||||
|
public TriangularPagerIndicator(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mLineHeight = UIUtil.dip2px(context, 3);
|
||||||
|
mTriangleWidth = UIUtil.dip2px(context, 14);
|
||||||
|
mTriangleHeight = UIUtil.dip2px(context, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
mPaint.setColor(mLineColor);
|
||||||
|
if (mReverse) {
|
||||||
|
canvas.drawRect(0, getHeight() - mYOffset - mTriangleHeight, getWidth(), getHeight() - mYOffset - mTriangleHeight + mLineHeight, mPaint);
|
||||||
|
} else {
|
||||||
|
canvas.drawRect(0, getHeight() - mLineHeight - mYOffset, getWidth(), getHeight() - mYOffset, mPaint);
|
||||||
|
}
|
||||||
|
mPath.reset();
|
||||||
|
if (mReverse) {
|
||||||
|
mPath.moveTo(mAnchorX - mTriangleWidth / 2, getHeight() - mYOffset - mTriangleHeight);
|
||||||
|
mPath.lineTo(mAnchorX, getHeight() - mYOffset);
|
||||||
|
mPath.lineTo(mAnchorX + mTriangleWidth / 2, getHeight() - mYOffset - mTriangleHeight);
|
||||||
|
} else {
|
||||||
|
mPath.moveTo(mAnchorX - mTriangleWidth / 2, getHeight() - mYOffset);
|
||||||
|
mPath.lineTo(mAnchorX, getHeight() - mTriangleHeight - mYOffset);
|
||||||
|
mPath.lineTo(mAnchorX + mTriangleWidth / 2, getHeight() - mYOffset);
|
||||||
|
}
|
||||||
|
mPath.close();
|
||||||
|
canvas.drawPath(mPath, mPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
if (mPositionDataList == null || mPositionDataList.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算锚点位置
|
||||||
|
PositionData current = FragmentContainerHelper.getImitativePositionData(mPositionDataList, position);
|
||||||
|
PositionData next = FragmentContainerHelper.getImitativePositionData(mPositionDataList, position + 1);
|
||||||
|
|
||||||
|
float leftX = current.mLeft + (current.mRight - current.mLeft) / 2;
|
||||||
|
float rightX = next.mLeft + (next.mRight - next.mLeft) / 2;
|
||||||
|
|
||||||
|
mAnchorX = leftX + (rightX - leftX) * mStartInterpolator.getInterpolation(positionOffset);
|
||||||
|
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPositionDataProvide(List<PositionData> dataList) {
|
||||||
|
mPositionDataList = dataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLineHeight() {
|
||||||
|
return mLineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLineHeight(int lineHeight) {
|
||||||
|
mLineHeight = lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLineColor() {
|
||||||
|
return mLineColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLineColor(int lineColor) {
|
||||||
|
mLineColor = lineColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTriangleHeight() {
|
||||||
|
return mTriangleHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTriangleHeight(int triangleHeight) {
|
||||||
|
mTriangleHeight = triangleHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTriangleWidth() {
|
||||||
|
return mTriangleWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTriangleWidth(int triangleWidth) {
|
||||||
|
mTriangleWidth = triangleWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Interpolator getStartInterpolator() {
|
||||||
|
return mStartInterpolator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartInterpolator(Interpolator startInterpolator) {
|
||||||
|
mStartInterpolator = startInterpolator;
|
||||||
|
if (mStartInterpolator == null) {
|
||||||
|
mStartInterpolator = new LinearInterpolator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReverse() {
|
||||||
|
return mReverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReverse(boolean reverse) {
|
||||||
|
mReverse = reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getYOffset() {
|
||||||
|
return mYOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYOffset(float yOffset) {
|
||||||
|
mYOffset = yOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.FragmentContainerHelper;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.UIUtil;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.model.PositionData;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 包裹住内容区域的指示器,类似天天快报的切换效果,需要和IMeasurablePagerTitleView配合使用
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class WrapPagerIndicator extends View implements IPagerIndicator {
|
||||||
|
private int mVerticalPadding;
|
||||||
|
private int mHorizontalPadding;
|
||||||
|
private int mFillColor;
|
||||||
|
private float mRoundRadius;
|
||||||
|
private Interpolator mStartInterpolator = new LinearInterpolator();
|
||||||
|
private Interpolator mEndInterpolator = new LinearInterpolator();
|
||||||
|
|
||||||
|
private List<PositionData> mPositionDataList;
|
||||||
|
private Paint mPaint;
|
||||||
|
|
||||||
|
private RectF mRect = new RectF();
|
||||||
|
private boolean mRoundRadiusSet;
|
||||||
|
|
||||||
|
public WrapPagerIndicator(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mVerticalPadding = UIUtil.dip2px(context, 6);
|
||||||
|
mHorizontalPadding = UIUtil.dip2px(context, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
mPaint.setColor(mFillColor);
|
||||||
|
canvas.drawRoundRect(mRect, mRoundRadius, mRoundRadius, mPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
if (mPositionDataList == null || mPositionDataList.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算锚点位置
|
||||||
|
PositionData current = FragmentContainerHelper.getImitativePositionData(mPositionDataList, position);
|
||||||
|
PositionData next = FragmentContainerHelper.getImitativePositionData(mPositionDataList, position + 1);
|
||||||
|
|
||||||
|
mRect.left = current.mContentLeft - mHorizontalPadding + (next.mContentLeft - current.mContentLeft) * mEndInterpolator.getInterpolation(positionOffset);
|
||||||
|
mRect.top = current.mContentTop - mVerticalPadding;
|
||||||
|
mRect.right = current.mContentRight + mHorizontalPadding + (next.mContentRight - current.mContentRight) * mStartInterpolator.getInterpolation(positionOffset);
|
||||||
|
mRect.bottom = current.mContentBottom + mVerticalPadding;
|
||||||
|
|
||||||
|
if (!mRoundRadiusSet) {
|
||||||
|
mRoundRadius = mRect.height() / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPositionDataProvide(List<PositionData> dataList) {
|
||||||
|
mPositionDataList = dataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Paint getPaint() {
|
||||||
|
return mPaint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVerticalPadding() {
|
||||||
|
return mVerticalPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVerticalPadding(int verticalPadding) {
|
||||||
|
mVerticalPadding = verticalPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHorizontalPadding() {
|
||||||
|
return mHorizontalPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHorizontalPadding(int horizontalPadding) {
|
||||||
|
mHorizontalPadding = horizontalPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFillColor() {
|
||||||
|
return mFillColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFillColor(int fillColor) {
|
||||||
|
mFillColor = fillColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getRoundRadius() {
|
||||||
|
return mRoundRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoundRadius(float roundRadius) {
|
||||||
|
mRoundRadius = roundRadius;
|
||||||
|
mRoundRadiusSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Interpolator getStartInterpolator() {
|
||||||
|
return mStartInterpolator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartInterpolator(Interpolator startInterpolator) {
|
||||||
|
mStartInterpolator = startInterpolator;
|
||||||
|
if (mStartInterpolator == null) {
|
||||||
|
mStartInterpolator = new LinearInterpolator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Interpolator getEndInterpolator() {
|
||||||
|
return mEndInterpolator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndInterpolator(Interpolator endInterpolator) {
|
||||||
|
mEndInterpolator = endInterpolator;
|
||||||
|
if (mEndInterpolator == null) {
|
||||||
|
mEndInterpolator = new LinearInterpolator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存指示器标题的坐标
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class PositionData {
|
||||||
|
public int mLeft;
|
||||||
|
public int mTop;
|
||||||
|
public int mRight;
|
||||||
|
public int mBottom;
|
||||||
|
public int mContentLeft;
|
||||||
|
public int mContentTop;
|
||||||
|
public int mContentRight;
|
||||||
|
public int mContentBottom;
|
||||||
|
|
||||||
|
public int width() {
|
||||||
|
return mRight - mLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int height() {
|
||||||
|
return mBottom - mTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int contentWidth() {
|
||||||
|
return mContentRight - mContentLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int contentHeight() {
|
||||||
|
return mContentBottom - mContentTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int horizontalCenter() {
|
||||||
|
return mLeft + width() / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int verticalCenter() {
|
||||||
|
return mTop + height() / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.titles;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.UIUtil;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IMeasurablePagerTitleView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类似今日头条切换效果的指示器标题
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class ClipPagerTitleView extends View implements IMeasurablePagerTitleView {
|
||||||
|
private String mText;
|
||||||
|
private int mTextColor;
|
||||||
|
private int mClipColor;
|
||||||
|
private boolean mLeftToRight;
|
||||||
|
private float mClipPercent;
|
||||||
|
|
||||||
|
private Paint mPaint;
|
||||||
|
private Rect mTextBounds = new Rect();
|
||||||
|
|
||||||
|
public ClipPagerTitleView(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
int textSize = UIUtil.dip2px(context, 16);
|
||||||
|
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mPaint.setTextSize(textSize);
|
||||||
|
int padding = UIUtil.dip2px(context, 10);
|
||||||
|
setPadding(padding, 0, padding, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
measureTextBounds();
|
||||||
|
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int measureWidth(int widthMeasureSpec) {
|
||||||
|
int mode = MeasureSpec.getMode(widthMeasureSpec);
|
||||||
|
int size = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
|
int result = size;
|
||||||
|
switch (mode) {
|
||||||
|
case MeasureSpec.AT_MOST:
|
||||||
|
int width = mTextBounds.width() + getPaddingLeft() + getPaddingRight();
|
||||||
|
result = Math.min(width, size);
|
||||||
|
break;
|
||||||
|
case MeasureSpec.UNSPECIFIED:
|
||||||
|
result = mTextBounds.width() + getPaddingLeft() + getPaddingRight();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int measureHeight(int heightMeasureSpec) {
|
||||||
|
int mode = MeasureSpec.getMode(heightMeasureSpec);
|
||||||
|
int size = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
int result = size;
|
||||||
|
switch (mode) {
|
||||||
|
case MeasureSpec.AT_MOST:
|
||||||
|
int height = mTextBounds.height() + getPaddingTop() + getPaddingBottom();
|
||||||
|
result = Math.min(height, size);
|
||||||
|
break;
|
||||||
|
case MeasureSpec.UNSPECIFIED:
|
||||||
|
result = mTextBounds.height() + getPaddingTop() + getPaddingBottom();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
int x = (getWidth() - mTextBounds.width()) / 2;
|
||||||
|
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
|
||||||
|
int y = (int) ((getHeight() - fontMetrics.bottom - fontMetrics.top) / 2);
|
||||||
|
|
||||||
|
// 画底层
|
||||||
|
mPaint.setColor(mTextColor);
|
||||||
|
canvas.drawText(mText, x, y, mPaint);
|
||||||
|
|
||||||
|
// 画clip层
|
||||||
|
canvas.save();
|
||||||
|
if (mLeftToRight) {
|
||||||
|
canvas.clipRect(0, 0, getWidth() * mClipPercent, getHeight());
|
||||||
|
} else {
|
||||||
|
canvas.clipRect(getWidth() * (1 - mClipPercent), 0, getWidth(), getHeight());
|
||||||
|
}
|
||||||
|
mPaint.setColor(mClipColor);
|
||||||
|
canvas.drawText(mText, x, y, mPaint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSelected(int index, int totalCount) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeselected(int index, int totalCount) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {
|
||||||
|
mLeftToRight = !leftToRight;
|
||||||
|
mClipPercent = 1.0f - leavePercent;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {
|
||||||
|
mLeftToRight = leftToRight;
|
||||||
|
mClipPercent = enterPercent;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void measureTextBounds() {
|
||||||
|
mPaint.getTextBounds(mText, 0, mText == null ? 0 : mText.length(), mTextBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return mText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
mText = text;
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getTextSize() {
|
||||||
|
return mPaint.getTextSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextSize(float textSize) {
|
||||||
|
mPaint.setTextSize(textSize);
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTextColor() {
|
||||||
|
return mTextColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextColor(int textColor) {
|
||||||
|
mTextColor = textColor;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClipColor() {
|
||||||
|
return mClipColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClipColor(int clipColor) {
|
||||||
|
mClipColor = clipColor;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentLeft() {
|
||||||
|
int contentWidth = mTextBounds.width();
|
||||||
|
return getLeft() + getWidth() / 2 - contentWidth / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentTop() {
|
||||||
|
Paint.FontMetrics metrics = mPaint.getFontMetrics();
|
||||||
|
float contentHeight = metrics.bottom - metrics.top;
|
||||||
|
return (int) (getHeight() / 2 - contentHeight / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentRight() {
|
||||||
|
int contentWidth = mTextBounds.width();
|
||||||
|
return getLeft() + getWidth() / 2 + contentWidth / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentBottom() {
|
||||||
|
Paint.FontMetrics metrics = mPaint.getFontMetrics();
|
||||||
|
float contentHeight = metrics.bottom - metrics.top;
|
||||||
|
return (int) (getHeight() / 2 + contentHeight / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.titles;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.ArgbEvaluatorHolder;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 两种颜色过渡的指示器标题
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class ColorTransitionPagerTitleView extends SimplePagerTitleView {
|
||||||
|
|
||||||
|
public ColorTransitionPagerTitleView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {
|
||||||
|
int color = ArgbEvaluatorHolder.eval(leavePercent, mSelectedColor, mNormalColor);
|
||||||
|
setTextColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {
|
||||||
|
int color = ArgbEvaluatorHolder.eval(enterPercent, mNormalColor, mSelectedColor);
|
||||||
|
setTextColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSelected(int index, int totalCount) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeselected(int index, int totalCount) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.titles;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IMeasurablePagerTitleView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用的指示器标题,子元素内容由外部提供,事件回传给外部
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/7/3.
|
||||||
|
*/
|
||||||
|
public class CommonPagerTitleView extends FrameLayout implements IMeasurablePagerTitleView {
|
||||||
|
private OnPagerTitleChangeListener mOnPagerTitleChangeListener;
|
||||||
|
private ContentPositionDataProvider mContentPositionDataProvider;
|
||||||
|
|
||||||
|
public CommonPagerTitleView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSelected(int index, int totalCount) {
|
||||||
|
if (mOnPagerTitleChangeListener != null) {
|
||||||
|
mOnPagerTitleChangeListener.onSelected(index, totalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeselected(int index, int totalCount) {
|
||||||
|
if (mOnPagerTitleChangeListener != null) {
|
||||||
|
mOnPagerTitleChangeListener.onDeselected(index, totalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {
|
||||||
|
if (mOnPagerTitleChangeListener != null) {
|
||||||
|
mOnPagerTitleChangeListener.onLeave(index, totalCount, leavePercent, leftToRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {
|
||||||
|
if (mOnPagerTitleChangeListener != null) {
|
||||||
|
mOnPagerTitleChangeListener.onEnter(index, totalCount, enterPercent, leftToRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentLeft() {
|
||||||
|
if (mContentPositionDataProvider != null) {
|
||||||
|
return mContentPositionDataProvider.getContentLeft();
|
||||||
|
}
|
||||||
|
return getLeft();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentTop() {
|
||||||
|
if (mContentPositionDataProvider != null) {
|
||||||
|
return mContentPositionDataProvider.getContentTop();
|
||||||
|
}
|
||||||
|
return getTop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentRight() {
|
||||||
|
if (mContentPositionDataProvider != null) {
|
||||||
|
return mContentPositionDataProvider.getContentRight();
|
||||||
|
}
|
||||||
|
return getRight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentBottom() {
|
||||||
|
if (mContentPositionDataProvider != null) {
|
||||||
|
return mContentPositionDataProvider.getContentBottom();
|
||||||
|
}
|
||||||
|
return getBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 外部直接将布局设置进来
|
||||||
|
*
|
||||||
|
* @param contentView
|
||||||
|
*/
|
||||||
|
public void setContentView(View contentView) {
|
||||||
|
setContentView(contentView, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentView(View contentView, FrameLayout.LayoutParams lp) {
|
||||||
|
removeAllViews();
|
||||||
|
if (contentView != null) {
|
||||||
|
if (lp == null) {
|
||||||
|
lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
}
|
||||||
|
addView(contentView, lp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentView(int layoutId) {
|
||||||
|
View child = LayoutInflater.from(getContext()).inflate(layoutId, null);
|
||||||
|
setContentView(child, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnPagerTitleChangeListener getOnPagerTitleChangeListener() {
|
||||||
|
return mOnPagerTitleChangeListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnPagerTitleChangeListener(OnPagerTitleChangeListener onPagerTitleChangeListener) {
|
||||||
|
mOnPagerTitleChangeListener = onPagerTitleChangeListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentPositionDataProvider getContentPositionDataProvider() {
|
||||||
|
return mContentPositionDataProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentPositionDataProvider(ContentPositionDataProvider contentPositionDataProvider) {
|
||||||
|
mContentPositionDataProvider = contentPositionDataProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnPagerTitleChangeListener {
|
||||||
|
void onSelected(int index, int totalCount);
|
||||||
|
|
||||||
|
void onDeselected(int index, int totalCount);
|
||||||
|
|
||||||
|
void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight);
|
||||||
|
|
||||||
|
void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ContentPositionDataProvider {
|
||||||
|
int getContentLeft();
|
||||||
|
|
||||||
|
int getContentTop();
|
||||||
|
|
||||||
|
int getContentRight();
|
||||||
|
|
||||||
|
int getContentBottom();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.titles;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerTitleView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空指示器标题,用于只需要指示器而不需要title的需求
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class DummyPagerTitleView extends View implements IPagerTitleView {
|
||||||
|
|
||||||
|
public DummyPagerTitleView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSelected(int index, int totalCount) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeselected(int index, int totalCount) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.titles;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.UIUtil;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IMeasurablePagerTitleView;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 带文本的指示器标题
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/6/26.
|
||||||
|
*/
|
||||||
|
public class SimplePagerTitleView extends TextView implements IMeasurablePagerTitleView {
|
||||||
|
protected int mSelectedColor;
|
||||||
|
protected int mNormalColor;
|
||||||
|
|
||||||
|
public SimplePagerTitleView(Context context) {
|
||||||
|
super(context, null);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
setGravity(Gravity.CENTER);
|
||||||
|
int padding = UIUtil.dip2px(context, 5);
|
||||||
|
setPadding(padding, 0, padding, 0);
|
||||||
|
setSingleLine();
|
||||||
|
setEllipsize(TextUtils.TruncateAt.END);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSelected(int index, int totalCount) {
|
||||||
|
setTextColor(mSelectedColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeselected(int index, int totalCount) {
|
||||||
|
setTextColor(mNormalColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentLeft() {
|
||||||
|
Rect bound = new Rect();
|
||||||
|
String longestString = "";
|
||||||
|
if (getText().toString().contains("\n")) {
|
||||||
|
String[] brokenStrings = getText().toString().split("\\n");
|
||||||
|
for (String each : brokenStrings) {
|
||||||
|
if (each.length() > longestString.length()) longestString = each;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
longestString = getText().toString();
|
||||||
|
}
|
||||||
|
getPaint().getTextBounds(longestString, 0, longestString.length(), bound);
|
||||||
|
int contentWidth = bound.width();
|
||||||
|
return getLeft() + getWidth() / 2 - contentWidth / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentTop() {
|
||||||
|
Paint.FontMetrics metrics = getPaint().getFontMetrics();
|
||||||
|
float contentHeight = metrics.bottom - metrics.top;
|
||||||
|
return (int) (getHeight() / 2 - contentHeight / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentRight() {
|
||||||
|
Rect bound = new Rect();
|
||||||
|
String longestString = "";
|
||||||
|
if (getText().toString().contains("\n")) {
|
||||||
|
String[] brokenStrings = getText().toString().split("\\n");
|
||||||
|
for (String each : brokenStrings) {
|
||||||
|
if (each.length() > longestString.length()) longestString = each;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
longestString = getText().toString();
|
||||||
|
}
|
||||||
|
getPaint().getTextBounds(longestString, 0, longestString.length(), bound);
|
||||||
|
int contentWidth = bound.width();
|
||||||
|
return getLeft() + getWidth() / 2 + contentWidth / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentBottom() {
|
||||||
|
Paint.FontMetrics metrics = getPaint().getFontMetrics();
|
||||||
|
float contentHeight = metrics.bottom - metrics.top;
|
||||||
|
return (int) (getHeight() / 2 + contentHeight / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSelectedColor() {
|
||||||
|
return mSelectedColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectedColor(int selectedColor) {
|
||||||
|
mSelectedColor = selectedColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNormalColor() {
|
||||||
|
return mNormalColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNormalColor(int normalColor) {
|
||||||
|
mNormalColor = normalColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.titles.badge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角标的锚点
|
||||||
|
* Created by hackware on 2016/7/19.
|
||||||
|
*/
|
||||||
|
public enum BadgeAnchor {
|
||||||
|
LEFT,
|
||||||
|
TOP,
|
||||||
|
RIGHT,
|
||||||
|
BOTTOM,
|
||||||
|
CONTENT_LEFT,
|
||||||
|
CONTENT_TOP,
|
||||||
|
CONTENT_RIGHT,
|
||||||
|
CONTENT_BOTTOM,
|
||||||
|
CENTER_X,
|
||||||
|
CENTER_Y,
|
||||||
|
LEFT_EDGE_CENTER_X,
|
||||||
|
TOP_EDGE_CENTER_Y,
|
||||||
|
RIGHT_EDGE_CENTER_X,
|
||||||
|
BOTTOM_EDGE_CENTER_Y
|
||||||
|
}
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.titles.badge;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IMeasurablePagerTitleView;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerTitleView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支持显示角标的title,角标布局可自定义
|
||||||
|
* 博客: http://hackware.lucode.net
|
||||||
|
* Created by hackware on 2016/7/18.
|
||||||
|
*/
|
||||||
|
public class BadgePagerTitleView extends FrameLayout implements IMeasurablePagerTitleView {
|
||||||
|
private IPagerTitleView mInnerPagerTitleView;
|
||||||
|
private View mBadgeView;
|
||||||
|
private boolean mAutoCancelBadge = true;
|
||||||
|
|
||||||
|
private BadgeRule mXBadgeRule;
|
||||||
|
private BadgeRule mYBadgeRule;
|
||||||
|
|
||||||
|
public BadgePagerTitleView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSelected(int index, int totalCount) {
|
||||||
|
if (mInnerPagerTitleView != null) {
|
||||||
|
mInnerPagerTitleView.onSelected(index, totalCount);
|
||||||
|
}
|
||||||
|
if (mAutoCancelBadge) {
|
||||||
|
setBadgeView(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeselected(int index, int totalCount) {
|
||||||
|
if (mInnerPagerTitleView != null) {
|
||||||
|
mInnerPagerTitleView.onDeselected(index, totalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {
|
||||||
|
if (mInnerPagerTitleView != null) {
|
||||||
|
mInnerPagerTitleView.onLeave(index, totalCount, leavePercent, leftToRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {
|
||||||
|
if (mInnerPagerTitleView != null) {
|
||||||
|
mInnerPagerTitleView.onEnter(index, totalCount, enterPercent, leftToRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPagerTitleView getInnerPagerTitleView() {
|
||||||
|
return mInnerPagerTitleView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInnerPagerTitleView(IPagerTitleView innerPagerTitleView) {
|
||||||
|
if (mInnerPagerTitleView == innerPagerTitleView) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mInnerPagerTitleView = innerPagerTitleView;
|
||||||
|
removeAllViews();
|
||||||
|
if (mInnerPagerTitleView instanceof View) {
|
||||||
|
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
|
||||||
|
addView((View) mInnerPagerTitleView, lp);
|
||||||
|
}
|
||||||
|
if (mBadgeView != null) {
|
||||||
|
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||||
|
addView(mBadgeView, lp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public View getBadgeView() {
|
||||||
|
return mBadgeView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBadgeView(View badgeView) {
|
||||||
|
if (mBadgeView == badgeView) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mBadgeView = badgeView;
|
||||||
|
removeAllViews();
|
||||||
|
if (mInnerPagerTitleView instanceof View) {
|
||||||
|
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
|
||||||
|
addView((View) mInnerPagerTitleView, lp);
|
||||||
|
}
|
||||||
|
if (mBadgeView != null) {
|
||||||
|
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||||
|
addView(mBadgeView, lp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||||
|
super.onLayout(changed, left, top, right, bottom);
|
||||||
|
if (mInnerPagerTitleView instanceof View && mBadgeView != null) {
|
||||||
|
int[] position = new int[14]; // 14种角标定位方式
|
||||||
|
View v = (View) mInnerPagerTitleView;
|
||||||
|
position[0] = v.getLeft();
|
||||||
|
position[1] = v.getTop();
|
||||||
|
position[2] = v.getRight();
|
||||||
|
position[3] = v.getBottom();
|
||||||
|
if (mInnerPagerTitleView instanceof IMeasurablePagerTitleView) {
|
||||||
|
IMeasurablePagerTitleView view = (IMeasurablePagerTitleView) mInnerPagerTitleView;
|
||||||
|
position[4] = view.getContentLeft();
|
||||||
|
position[5] = view.getContentTop();
|
||||||
|
position[6] = view.getContentRight();
|
||||||
|
position[7] = view.getContentBottom();
|
||||||
|
} else {
|
||||||
|
for (int i = 4; i < 8; i++) {
|
||||||
|
position[i] = position[i - 4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
position[8] = v.getWidth() / 2;
|
||||||
|
position[9] = v.getHeight() / 2;
|
||||||
|
position[10] = position[4] / 2;
|
||||||
|
position[11] = position[5] / 2;
|
||||||
|
position[12] = position[6] + (position[2] - position[6]) / 2;
|
||||||
|
position[13] = position[7] + (position[3] - position[7]) / 2;
|
||||||
|
|
||||||
|
// 根据设置的BadgeRule调整角标的位置
|
||||||
|
if (mXBadgeRule != null) {
|
||||||
|
int x = position[mXBadgeRule.getAnchor().ordinal()];
|
||||||
|
int offset = mXBadgeRule.getOffset();
|
||||||
|
int newLeft = x + offset;
|
||||||
|
mBadgeView.offsetLeftAndRight(newLeft - mBadgeView.getLeft());
|
||||||
|
}
|
||||||
|
if (mYBadgeRule != null) {
|
||||||
|
int y = position[mYBadgeRule.getAnchor().ordinal()];
|
||||||
|
int offset = mYBadgeRule.getOffset();
|
||||||
|
int newTop = y + offset;
|
||||||
|
mBadgeView.offsetTopAndBottom(newTop - mBadgeView.getTop());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentLeft() {
|
||||||
|
if (mInnerPagerTitleView instanceof IMeasurablePagerTitleView) {
|
||||||
|
return getLeft() + ((IMeasurablePagerTitleView) mInnerPagerTitleView).getContentLeft();
|
||||||
|
}
|
||||||
|
return getLeft();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentTop() {
|
||||||
|
if (mInnerPagerTitleView instanceof IMeasurablePagerTitleView) {
|
||||||
|
return ((IMeasurablePagerTitleView) mInnerPagerTitleView).getContentTop();
|
||||||
|
}
|
||||||
|
return getTop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentRight() {
|
||||||
|
if (mInnerPagerTitleView instanceof IMeasurablePagerTitleView) {
|
||||||
|
return getLeft() + ((IMeasurablePagerTitleView) mInnerPagerTitleView).getContentRight();
|
||||||
|
}
|
||||||
|
return getRight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentBottom() {
|
||||||
|
if (mInnerPagerTitleView instanceof IMeasurablePagerTitleView) {
|
||||||
|
return ((IMeasurablePagerTitleView) mInnerPagerTitleView).getContentBottom();
|
||||||
|
}
|
||||||
|
return getBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BadgeRule getXBadgeRule() {
|
||||||
|
return mXBadgeRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXBadgeRule(BadgeRule badgeRule) {
|
||||||
|
if (badgeRule != null) {
|
||||||
|
BadgeAnchor anchor = badgeRule.getAnchor();
|
||||||
|
if (anchor != BadgeAnchor.LEFT
|
||||||
|
&& anchor != BadgeAnchor.RIGHT
|
||||||
|
&& anchor != BadgeAnchor.CONTENT_LEFT
|
||||||
|
&& anchor != BadgeAnchor.CONTENT_RIGHT
|
||||||
|
&& anchor != BadgeAnchor.CENTER_X
|
||||||
|
&& anchor != BadgeAnchor.LEFT_EDGE_CENTER_X
|
||||||
|
&& anchor != BadgeAnchor.RIGHT_EDGE_CENTER_X) {
|
||||||
|
throw new IllegalArgumentException("x badge rule is wrong.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mXBadgeRule = badgeRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BadgeRule getYBadgeRule() {
|
||||||
|
return mYBadgeRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYBadgeRule(BadgeRule badgeRule) {
|
||||||
|
if (badgeRule != null) {
|
||||||
|
BadgeAnchor anchor = badgeRule.getAnchor();
|
||||||
|
if (anchor != BadgeAnchor.TOP
|
||||||
|
&& anchor != BadgeAnchor.BOTTOM
|
||||||
|
&& anchor != BadgeAnchor.CONTENT_TOP
|
||||||
|
&& anchor != BadgeAnchor.CONTENT_BOTTOM
|
||||||
|
&& anchor != BadgeAnchor.CENTER_Y
|
||||||
|
&& anchor != BadgeAnchor.TOP_EDGE_CENTER_Y
|
||||||
|
&& anchor != BadgeAnchor.BOTTOM_EDGE_CENTER_Y) {
|
||||||
|
throw new IllegalArgumentException("y badge rule is wrong.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mYBadgeRule = badgeRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAutoCancelBadge() {
|
||||||
|
return mAutoCancelBadge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoCancelBadge(boolean autoCancelBadge) {
|
||||||
|
mAutoCancelBadge = autoCancelBadge;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package net.lucode.hackware.magicindicator.buildins.commonnavigator.titles.badge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角标的定位规则
|
||||||
|
* Created by hackware on 2016/7/19.
|
||||||
|
*/
|
||||||
|
public class BadgeRule {
|
||||||
|
private BadgeAnchor mAnchor;
|
||||||
|
private int mOffset;
|
||||||
|
|
||||||
|
public BadgeRule(BadgeAnchor anchor, int offset) {
|
||||||
|
mAnchor = anchor;
|
||||||
|
mOffset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BadgeAnchor getAnchor() {
|
||||||
|
return mAnchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAnchor(BadgeAnchor anchor) {
|
||||||
|
mAnchor = anchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOffset() {
|
||||||
|
return mOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffset(int offset) {
|
||||||
|
mOffset = offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/scroll_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fadingEdge="none"
|
||||||
|
android:scrollbars="none">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/indicator_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/title_container"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/indicator_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/title_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
@@ -1 +1 @@
|
|||||||
include ':app', ':customer', ':base', ':device', ':http', ':media', ':messaging', ':storage', ':uikit', ':location', ':citypicker', ':share', ':yunxinkit', ':faceunity'
|
include ':app', ':customer', ':base', ':device', ':http', ':media', ':messaging', ':storage', ':uikit', ':location', ':citypicker', ':share', ':yunxinkit', ':faceunity',':magicindicator'
|
||||||
|
|||||||
@@ -81,6 +81,7 @@
|
|||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:visibility="gone"
|
||||||
android:id="@+id/bottom_tab_live_layout"
|
android:id="@+id/bottom_tab_live_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|||||||
Reference in New Issue
Block a user