Commit 28a54830 authored by mengcuiguang's avatar mengcuiguang

修改大转盘

parent 4434c354
......@@ -8,6 +8,7 @@ local.properties
/gradle
#lib project
app/build
wheelsruflibray/build
shareSdkLib/build
picture_library/build
ucrop/build
......
......@@ -9,8 +9,8 @@ android {
applicationId "com.mints.goodmoney"
minSdkVersion rootProject.ext.androidMinSdkVersion
targetSdkVersion rootProject.ext.androidTargetSdkVersion
versionCode 22
versionName "1.2.1"
versionCode 23
versionName "1.2.2"
flavorDimensions "default"
// dex突破65535的限制
......@@ -179,6 +179,11 @@ dependencies {
implementation 'com.mindorks.android:prdownloader:0.6.0'
// 圆角库
implementation 'com.github.SheHuan:NiceImageView:1.0.5'
// 跑马灯
implementation 'com.sunfusheng:marqueeview:1.2.0'
// 转盘
implementation project(':wheelsruflibrary')
// 工具类
// gson
......@@ -232,12 +237,6 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.0"
implementation 'com.liulishuo.filedownloader:library:1.7.7'
implementation "org.greenrobot:eventbus:3.1.0-RC"
// 掌阅书城
implementation(name: 'iReader-release-1.0.1', ext: 'aar')
implementation 'com.alibaba:fastjson:1.2.11'
implementation 'androidx.annotation:annotation:1.0.0'
implementation 'androidx.core:core:1.0.0'
implementation 'androidx.fragment:fragment:1.0.0'
// 变现猫
implementation(name: 'bxmsdk-release-3.3.1', ext: 'aar')
// 闪电盒子
......@@ -282,6 +281,7 @@ dependencies {
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.2'
implementation 'com.squareup.retrofit2:converter-scalars:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
implementation 'com.alibaba:fastjson:1.2.11'
// 激励视频RTA
......
......@@ -427,42 +427,6 @@
# ===================== 推啊AD START ================
-dontwarn com.lechuan.midunovel.**
-keep class com.lechuan.midunovel.** { *; }
# ======================= 推啊AD END ================
# ===================== 掌阅书城 START ================
-keep class com.zhangyue.**{*;}
-keep class com.ireader.ireadersdk.IreaderApi {*;}
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
-keep public class * extends androidx.fragment.app.Fragment
-keep class androidx.core.app.NotificationCompat**{
public *;
}
-dontwarn androidx.**
-keep class androidx.** { *;}
-keep public class * extends androidx.**
-keep public class * extends androidx.fragment.app.FragmentContainer
-keep class com.squareup.okhttp.** { *;}
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-keep class okio.**{ *; }
-keep interface okio.**{ *; }
-dontwarn com.squareup.okhttp.**
-dontwarn okio.**
-dontwarn okhttp3.**
-keep class com.qq.e.** {
public protected *;
}
# ======================= 掌阅书城 END ================
......
package com.mints.goodmoney.manager
import android.app.Application
import com.ireader.ireadersdk.IreaderApi
import com.mints.goodmoney.MintsApplication
import java.lang.Exception
/**
* 描述:掌阅书城
* 作者:孟崔广
*/
object ZhangyueManager {
private const val APPID = "10054"
fun onCreateIreader(application: Application) {
// try {
// IreaderApi.onCreate(application)
// val config = Config.Builder()
// .setZYAppId(APPID)
// .setOaId(MintsApplication.OAID)
// .setSupportCSJ(true)
// .setSupportGDT(true)
// .build()
// IreaderApi.attachBaseContext(application, config)
// } catch (e: Exception) {
// e.printStackTrace()
// }
try {
IreaderApi.attachBaseContext(application)
IreaderApi.onCreate(application, APPID)
} catch (e: Exception) {
e.printStackTrace()
}
}
fun onDestory() {
IreaderApi.onAppExit()
}
}
\ No newline at end of file
package com.mints.goodmoney.mvp.model;
import java.io.Serializable;
public class ClickTurnBean implements Serializable {
/**
* config : {"count":250,"type":"coin","key":"t5","index":5,"title":"250金币"}
* sumCoin : 7580
* coinKey : 2108214495303800003
* turntableKey : 2108214495303800003
*/
private ConfigBean config;
private int sumCoin;
private String coinKey;
private String turntableKey;
public ConfigBean getConfig() {
return config;
}
public void setConfig(ConfigBean config) {
this.config = config;
}
public int getSumCoin() {
return sumCoin;
}
public void setSumCoin(int sumCoin) {
this.sumCoin = sumCoin;
}
public String getCoinKey() {
return coinKey;
}
public void setCoinKey(String coinKey) {
this.coinKey = coinKey;
}
public String getTurntableKey() {
return turntableKey;
}
public void setTurntableKey(String turntableKey) {
this.turntableKey = turntableKey;
}
public class ConfigBean implements Serializable{
/**
* count : 250
* type : coin
* key : t5
* index : 5
* title : 250金币
*/
private int count;
private String type;
private String key;
private int index;
private String title;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
}
package com.mints.goodmoney.mvp.model;
import java.io.Serializable;
import java.util.List;
public class TurnBean implements Serializable {
/**
* configs : [{"count":150,"type":"coin","key":"t1","index":0,"title":"150金币"},{"count":10,"type":"cash","key":"t2","index":1,"title":"现金10元"},{"count":200,"type":"coin","key":"t8","index":2,"title":"200金币"},{"count":100,"type":"coin","key":"t3","index":3,"title":"100金币"},{"count":300,"type":"coin","key":"t4","index":4,"title":"300金币"},{"count":250,"type":"coin","key":"t5","index":5,"title":"250金币"},{"count":350,"type":"coin","key":"t6","index":6,"title":"350金币"},{"count":40,"type":"cash","key":"t7","index":7,"title":"现金40元"}]
* max : 30
*/
private List<ConfigsBean> configs;
private int max;
private String titleMsg;
private int surplus;
private List<BottomsBean> bottoms;
public List<ConfigsBean> getConfigs() {
return configs;
}
public String getTitleMsg() {
return titleMsg;
}
public void setTitleMsg(String titleMsg) {
this.titleMsg = titleMsg;
}
public int getSurplus() {
return surplus;
}
public void setSurplus(int surplus) {
this.surplus = surplus;
}
public void setConfigs(List<ConfigsBean> configs) {
this.configs = configs;
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
public List<BottomsBean> getBottoms() {
return bottoms;
}
public void setBottoms(List<BottomsBean> bottoms) {
this.bottoms = bottoms;
}
public class BottomsBean implements Serializable {
/**
* title : 高额赚
* icon : https://mints-pkg.oss-cn-beijing.aliyuncs.com/pkg_goodmoney/img/readnews.png
* toOtherKey : 1
* rewardTitle : 抽奖 +1
*/
private String title;
private String icon;
private String toOtherKey;
private String rewardTitle;
private ParamsBean params;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public String getToOtherKey() {
return toOtherKey;
}
public void setToOtherKey(String toOtherKey) {
this.toOtherKey = toOtherKey;
}
public String getRewardTitle() {
return rewardTitle;
}
public void setRewardTitle(String rewardTitle) {
this.rewardTitle = rewardTitle;
}
public class ParamsBean implements Serializable {
private int max;
private int complete;
private int coin;
public int getMax() {
return max;
}
public int getComplete() {
return complete;
}
public int getCoin() {
return coin;
}
}
}
public class ConfigsBean implements Serializable {
/**
* count : 150
* type : coin
* key : t1
* index : 0
* title : 150金币
*/
private int count;
private String type;
private String key;
private int index;
private String title;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
}
package com.mints.goodmoney.mvp.presenters
import android.text.TextUtils
import com.mints.goodmoney.MintsApplication
import com.mints.goodmoney.common.DeviceInfo
import com.mints.library.net.neterror.BaseSubscriber
import com.mints.library.net.neterror.Throwable
import com.mints.goodmoney.manager.AppHttpManager
import com.mints.goodmoney.manager.ShumeiManager
import com.mints.goodmoney.manager.UserManager
import com.mints.goodmoney.mvp.model.BaseResponse
import com.mints.goodmoney.mvp.model.ClickTurnBean
import com.mints.goodmoney.mvp.model.TurnBean
import com.mints.goodmoney.mvp.model.UserBean
import com.mints.goodmoney.mvp.views.PanView
import com.mints.goodmoney.mvp.views.TurnTableView
import com.mints.goodmoney.utils.DeviceUuidFactory
import java.util.*
class TurnTablePresenter : BasePresenter<TurnTableView>() {
fun getTurnMsg() {
AppHttpManager.getInstance(loanApplication)
.call(loanService.getTurnMsg(),
object : BaseSubscriber<BaseResponse<TurnBean>>() {
override fun onCompleted() {
}
override fun onError(e: Throwable) {
if (isLinkView) return
view.showToast(e.message)
}
override fun onNext(baseResponse: BaseResponse<TurnBean>) {
if (isLinkView) return
val code = baseResponse.getStatus()
val message = baseResponse.getMessage()
when (code) {
200 -> {
view.getTurnTableSuc(baseResponse.data)
}
else -> view.showToast(message)
}
}
})
}
fun addTurnToOtherMsg(toOtherKey: String) {
val vo = HashMap<String, Any>()
vo["toOther"] = toOtherKey
AppHttpManager.getInstance(loanApplication)
.call(loanService.addTurnToOtherMsg(vo),
object : BaseSubscriber<BaseResponse<Any>>() {
override fun onCompleted() {
}
override fun onError(e: Throwable) {
if (isLinkView) return
view.showToast(e.message)
}
override fun onNext(baseResponse: BaseResponse<Any>) {
if (isLinkView) return
val code = baseResponse.getStatus()
val message = baseResponse.getMessage()
when (code) {
200 -> {
}
else -> view.showToast(message)
}
}
})
}
fun cashoutLeaders() {
AppHttpManager.getInstance(loanApplication)
.call(loanService.cashoutLeaders(),
object : BaseSubscriber<BaseResponse<Any>>() {
override fun onCompleted() {
}
override fun onError(e: Throwable) {
if (isLinkView) return
view.showToast(e.message)
}
override fun onNext(baseResponse: BaseResponse<Any>) {
if (isLinkView) return
val code = baseResponse.getStatus()
val message = baseResponse.getMessage()
when (code) {
200 -> {
view.cashoutLeadersSuc()
}
else -> view.showToast(message)
}
}
})
}
fun clickForTurn() {
AppHttpManager.getInstance(loanApplication)
.call(loanService.clickForTurn(),
object : BaseSubscriber<BaseResponse<ClickTurnBean>>() {
override fun onCompleted() {
}
override fun onError(e: Throwable) {
if (isLinkView) return
view.showToast(e.message)
}
override fun onNext(baseResponse: BaseResponse<ClickTurnBean>) {
if (isLinkView) return
val code = baseResponse.getStatus()
val message = baseResponse.getMessage()
when (code) {
200 -> {
view.clickForTurnSuc(baseResponse.data)
}
else -> view.showToast(message)
}
}
})
}
/**
* 游客登录
*/
fun userLogin() {
val vo = HashMap<String, Any>()
vo["device"] = DeviceUuidFactory().deviceUuid.toString()
vo["shumeiId"] = ShumeiManager.getInstance().shumeiDeviceId
AppHttpManager.getInstance(loanApplication)
.call(loanService.visitorlogin(vo),
object : BaseSubscriber<BaseResponse<UserBean>>() {
override fun onCompleted() {
}
override fun onError(e: Throwable) {
}
override fun onNext(baseResponse: BaseResponse<UserBean>) {
if (isLinkView) return
val code = baseResponse.getStatus()
val message = baseResponse.getMessage()
val data: UserBean? = baseResponse.getData()
when (code) {
200 -> if (data != null) {
UserManager.getInstance().saveUserInfo(data)
saveTerminalInfo()
}
else -> view.showToast(message)
}
}
})
}
/**
* 提交设备信息
*
* @param context
*/
fun saveTerminalInfo() {
val vo = HashMap<String, Any>()
val deviceInfo: DeviceInfo = DeviceInfo.instance
val macAddress: String = deviceInfo.getMacAddress()
val mac = macAddress.replace(":", "")
vo["mac"] = mac
vo["mac1"] = macAddress
vo["androidid"] = deviceInfo.getAndroidId(null)
vo["imei"] = deviceInfo.iMEI
if (!TextUtils.isEmpty(MintsApplication.OAID)) {
vo["oaid"] = MintsApplication.OAID
}
vo["os"] = "android"
vo["model"] = deviceInfo.newModel
vo["uuid"] = DeviceUuidFactory().deviceUuid
vo["osversion"] = deviceInfo.oSVersion
vo["appversion"] = deviceInfo.versionName
vo["shumeiId"] = ShumeiManager.getInstance().getShumeiDeviceId()
AppHttpManager.getInstance(loanApplication)
.call(loanService.saveTerminalInfo(vo),
object : BaseSubscriber<BaseResponse<Any>>() {
override fun onCompleted() {
if (isLinkView) return
}
override fun onError(e: Throwable) {
if (isLinkView) return
}
override fun onNext(baseResponse: BaseResponse<Any>) {
if (isLinkView) return
val code = baseResponse.status
when (code) {
200 -> {
getTurnMsg()
}
}
}
})
}
}
\ No newline at end of file
package com.mints.goodmoney.mvp.views
import com.mints.goodmoney.mvp.model.ClickTurnBean
import com.mints.goodmoney.mvp.model.TurnBean
interface TurnTableView : BaseView {
fun getTurnTableSuc(data: TurnBean)
fun cashoutLeadersSuc()
fun clickForTurnSuc(data: ClickTurnBean)
}
\ No newline at end of file
......@@ -7,6 +7,7 @@ import com.mints.goodmoney.BuildConfig;
import com.mints.goodmoney.mvp.model.AccountMsgBean;
import com.mints.goodmoney.mvp.model.BannerBean;
import com.mints.goodmoney.mvp.model.BaseResponse;
import com.mints.goodmoney.mvp.model.ClickTurnBean;
import com.mints.goodmoney.mvp.model.CommonParamBean;
import com.mints.goodmoney.mvp.model.DrawcashBean;
import com.mints.goodmoney.mvp.model.DrawcashRecordBean;
......@@ -20,6 +21,7 @@ import com.mints.goodmoney.mvp.model.MorningClockBean;
import com.mints.goodmoney.mvp.model.MyInfo;
import com.mints.goodmoney.mvp.model.SignCardBean;
import com.mints.goodmoney.mvp.model.TaskCpdBean;
import com.mints.goodmoney.mvp.model.TurnBean;
import com.mints.goodmoney.mvp.model.UserBean;
import com.mints.goodmoney.mvp.model.UserTaskMsgBean;
import com.mints.goodmoney.mvp.model.Version;
......@@ -577,6 +579,38 @@ public interface LoanService {
@POST("common/reportErrornterface")
Observable<BaseResponse<JsonObject>> reportErrornterface(@Body Map<String, Object> vo);
/**
* 获取大转盘信息
*
* @return
*/
@POST("api/turn/getTurnMsg")
Observable<BaseResponse<TurnBean>> getTurnMsg();
/**
* 点击获取转盘信息
*
* @return
*/
@POST("api/turn/clickForTurn")
Observable<BaseResponse<ClickTurnBean>> clickForTurn();
/**
* 提现列表展示
*
* @return
*/
@POST("common/cashoutLeaders")
Observable<BaseResponse<Object>> cashoutLeaders();
/**
* 大转盘点击入口
*
* @return
*/
@POST("api/turn/addTurnToOtherMsg")
Observable<BaseResponse<Object>> addTurnToOtherMsg(@Body Map<String, Object> vo);
/**
* 默认http工厂
*/
......@@ -591,29 +625,29 @@ public interface LoanService {
builder.readTimeout(20, TimeUnit.SECONDS);
builder.writeTimeout(20, TimeUnit.SECONDS);
// if (BuildConfig.DEBUG) {
// HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// logging.setLevel(HttpLoggingInterceptor.Level.BODY);
// builder.interceptors().add(logging);
// }
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> {
if (TextUtils.isEmpty(message)) return;
String s = message.substring(0, 1);
String request = message.substring(0, 4);
if ("{".equals(s) || "[".equals(s)) {
Logger.json(message);
} else if (request.contains("-->") || request.contains("<--")) {
Logger.d("Method" + message);
} else {
Logger.d("params:" + message);
}
});
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.interceptors().add(logging);
}
// if (BuildConfig.DEBUG) {
// HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> {
// if (TextUtils.isEmpty(message)) return;
// String s = message.substring(0, 1);
// String request = message.substring(0, 4);
// if ("{".equals(s) || "[".equals(s)) {
// Logger.json(message);
// } else if (request.contains("-->") || request.contains("<--")) {
// Logger.d("Method" + message);
// } else {
// Logger.d("params:" + message);
// }
// });
// logging.setLevel(HttpLoggingInterceptor.Level.BODY);
// builder.interceptors().add(logging);
// }
OkHttpInterceptor okHttpInterceptor = new OkHttpInterceptor(AESUtils.getDefaultKey());
// builder.interceptors().add(domainInterceptor);
builder.interceptors().add(okHttpInterceptor);
......
......@@ -9,7 +9,6 @@ import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import com.ireader.ireadersdk.IreaderApi
import com.mints.goodmoney.R
import com.mints.goodmoney.ad.express.TTPreLoadCarrierExpressManager
import com.mints.goodmoney.ad.video.VideoAdingManager
......@@ -18,7 +17,6 @@ import com.mints.goodmoney.common.Constant
import com.mints.goodmoney.manager.MokuManager
import com.mints.goodmoney.manager.SceneManager
import com.mints.goodmoney.manager.UserManager
import com.mints.goodmoney.manager.ZhangyueManager
import com.mints.goodmoney.mvp.views.MainView
import com.mints.goodmoney.ui.activitys.base.BaseActivity
import com.mints.goodmoney.ui.fragment.*
......@@ -36,7 +34,7 @@ class MainActivity : BaseActivity(), MainView, View.OnClickListener {
// 底部标签切换的Fragment
private var moneyFragment: Fragment? = null
private var panFragment: Fragment? = null
private var turnTableFragment: Fragment? = null
private var friendsFragment: Fragment? = null
private var myFragment: Fragment? = null
......@@ -52,8 +50,6 @@ class MainActivity : BaseActivity(), MainView, View.OnClickListener {
override fun getContentViewLayoutID() = R.layout.activity_main
override fun initViewsAndEvents() {
ZhangyueManager.onCreateIreader(baseApplication)
showShortVedioLayout()
if (moneyFragment == null) {
......@@ -101,8 +97,6 @@ class MainActivity : BaseActivity(), MainView, View.OnClickListener {
override fun isApplyKitKatTranslucency() = false
public override fun onDestroy() {
IreaderApi.onAppExit()
super.onDestroy()
TTPreLoadCarrierExpressManager.getInstance().onDestroy()
......@@ -269,10 +263,10 @@ class MainActivity : BaseActivity(), MainView, View.OnClickListener {
*/
private fun clickTab3Layout() {
AppConfig.fragmentClickFlag = Constant.FRAGMENT_CLICK_THREE
if (panFragment == null) {
panFragment = PanFragment()
if (turnTableFragment == null) {
turnTableFragment = TurnTableFragment()
}
addOrShowFragment(supportFragmentManager, panFragment!!, Constant.FRAGMENT_TAG_THREE)
addOrShowFragment(supportFragmentManager, turnTableFragment!!, Constant.FRAGMENT_TAG_THREE)
tab_iv_one.isSelected = false
tab_tv_one.isSelected = false
tab_iv_two.isSelected = false
......
......@@ -52,14 +52,10 @@ class WrapperActivity : BaseActivity(), View.OnClickListener {
Constant.WRAPPER_TYPE_NEWS -> {
layoutWrapper.visibility = View.INVISIBLE
val layoutParams = layoutWrapper.layoutParams
layoutParams.height=BubbleUtils.dp2px(30)
layoutParams.height = BubbleUtils.dp2px(30)
tv_title.text = "新闻"
currentFragment = RsNewsFragment()
}
Constant.WRAPPER_TYPE_BOOK -> {
tv_title.text = "书城"
currentFragment = MyZhangyueFragment()
}
Constant.WRAPPER_TYPE_FRIENDS -> {
tv_title.text = "瓜分百万现金福利"
currentFragment = FriendsFragment(true)
......@@ -73,8 +69,8 @@ class WrapperActivity : BaseActivity(), View.OnClickListener {
currentFragment = WzFragment(true)
}
else -> {
tv_title.text = "书城"
currentFragment = MyZhangyueFragment()
tv_title.text = "瓜分百万现金福利"
currentFragment = FriendsFragment(true)
}
}
......
package com.mints.goodmoney.ui.adapter;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.mints.goodmoney.R;
import com.mints.goodmoney.common.Constant;
import com.mints.goodmoney.manager.BxmManager;
import com.mints.goodmoney.manager.UserManager;
import com.mints.goodmoney.mvp.model.BannerBean;
import com.mints.goodmoney.mvp.model.TurnBean;
import com.mints.library.utils.GlideUtils;
import java.util.List;
public class TurnTableAdapter extends BaseAdapter {
private List<TurnBean.BottomsBean> orders;
private Activity activity;
public TurnTableAdapter(Activity activity, List<TurnBean.BottomsBean> orders) {
this.orders = orders;
this.activity = activity;
}
@Override
public int getCount() {
return orders == null ? 0 : orders.size();
}
@Override
public Object getItem(int position) {
return orders.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@SuppressLint("WrongViewCast")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(activity);
convertView = inflater.inflate(R.layout.item_list_turn, null);
viewHolder = new ViewHolder();
viewHolder.ic_turn_icon = convertView.findViewById(R.id.ic_turn_icon);
viewHolder.tv_turn_top = convertView.findViewById(R.id.tv_turn_top);
viewHolder.tv_turn_bottom = convertView.findViewById(R.id.tv_turn_bottom);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
TurnBean.BottomsBean data = orders.get(position);
if (data != null) {
GlideUtils.loadImageView(activity, data.getIcon(), viewHolder.ic_turn_icon);
viewHolder.tv_turn_top.setText(TextUtils.isEmpty(data.getRewardTitle()) ? "" : data.getRewardTitle());
viewHolder.tv_turn_bottom.setText(data.getTitle());
}
return convertView;
}
class ViewHolder {
public ImageView ic_turn_icon;
public TextView tv_turn_top;
public TextView tv_turn_bottom;
}
}
......@@ -27,7 +27,7 @@ class MoneyFragment : BaseFragment(), XTabLayout.OnTabSelectedListener {
private var currentFragment: Fragment? = null
private var mainFragment: Fragment? = null
private var bookStoreFragment: Fragment? = null
// private var bookStoreFragment: Fragment? = null
// private var newsFragment: Fragment? = null
private var xmlyGameFragment: Fragment? = null
......@@ -73,11 +73,9 @@ class MoneyFragment : BaseFragment(), XTabLayout.OnTabSelectedListener {
currentFragment = mainFragment
}
xtFragmentMoney.setxTabDisplayNum(5)
xtFragmentMoney.setxTabDisplayNum(4)
val newTab1 = xtFragmentMoney.newTab()
newTab1.text = "视频"
val newTab2 = xtFragmentMoney.newTab()
newTab2.text = "书城"
// val newTab3 = xtFragmentMoney.newTab()
// newTab3.text = "新闻"
val newTab4 = xtFragmentMoney.newTab()
......@@ -87,7 +85,6 @@ class MoneyFragment : BaseFragment(), XTabLayout.OnTabSelectedListener {
val newTab6 = xtFragmentMoney.newTab()
newTab6.text = "来电秀"
xtFragmentMoney.addTab(newTab1)
xtFragmentMoney.addTab(newTab2)
// xtFragmentMoney.addTab(newTab3)
xtFragmentMoney.addTab(newTab4)
xtFragmentMoney.addTab(newTab5)
......@@ -144,17 +141,10 @@ class MoneyFragment : BaseFragment(), XTabLayout.OnTabSelectedListener {
}
fun selectBook() {
// vpFragmentMoney.currentItem = 1
xtFragmentMoney.getTabAt(1)?.select()
if (bookStoreFragment == null) {
bookStoreFragment = ZhangyueFragment()
}
addOrShowFragment(childFragmentManager, bookStoreFragment!!, FRAGMENT_TAG_BOOKSTORE)
}
fun selectXmly() {
xtFragmentMoney.getTabAt(2)?.select()
xtFragmentMoney.getTabAt(1)?.select()
if (xmlyGameFragment == null) {
xmlyGameFragment = XmlyFragment()
}
......@@ -184,30 +174,18 @@ class MoneyFragment : BaseFragment(), XTabLayout.OnTabSelectedListener {
}
1 -> {
if (bookStoreFragment == null) {
bookStoreFragment = ZhangyueFragment()
}
addOrShowFragment(childFragmentManager, bookStoreFragment!!, FRAGMENT_TAG_BOOKSTORE)
}
// 2 -> {
// if (newsFragment == null) {
// newsFragment = RsNewsFragment()
// }
// addOrShowFragment(childFragmentManager, newsFragment!!, FRAGMENT_TAG_NEWS)
// }
2 -> {
if (xmlyGameFragment == null) {
xmlyGameFragment = XmlyFragment()
}
addOrShowFragment(childFragmentManager, xmlyGameFragment!!, FRAGMENT_TAG_XMLY)
}
3 -> {
2 -> {
if (liebaoGameFragment == null) {
liebaoGameFragment = LiebaoGameFragment()
}
addOrShowFragment(childFragmentManager, liebaoGameFragment!!, FRAGMENT_TAG_GAME)
}
4 -> {
3 -> {
if (kuYinyueFragment == null) {
kuYinyueFragment = KuYinYueFragment()
}
......
package com.mints.goodmoney.ui.fragment
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import com.ireader.ireadersdk.IreaderApi
import com.mints.goodmoney.R
import com.mints.goodmoney.common.AppConfig
import com.mints.goodmoney.common.Constant
import com.mints.goodmoney.manager.ZhangyueManager
import com.mints.goodmoney.mvp.presenters.BookPresenter
import com.mints.goodmoney.mvp.views.BookView
import com.mints.goodmoney.ui.activitys.AwardActivity
import com.mints.goodmoney.ui.fragment.base.LazyLoadBaseFragment
import com.mints.goodmoney.utils.SpanUtils
import kotlinx.android.synthetic.main.fragment_main_zy.*
/**
* 描述:我的-掌阅书城
* 作者:孟崔广
*/
class MyZhangyueFragment : LazyLoadBaseFragment(), BookView, IreaderApi.OnReadChangeListener {
private val bookPresenter by lazy { BookPresenter() }
private var bookFragment: Fragment? = null
override fun getContentViewLayoutID() = R.layout.fragment_main_zy
override fun initViewsAndEvents() {
bookPresenter.attachView(this)
val transaction: FragmentTransaction = supportFragmentManager.beginTransaction()
if (bookFragment == null) {
// bookFragment = IreaderApi.getNovelBookStoreFragment()
bookFragment = IreaderApi.getNovelChannelFragment()
transaction.add(R.id.fragment, bookFragment!!, bookFragment!!::class.java.simpleName)
IreaderApi.setReadChangeListener(this)
} else {
transaction.show(bookFragment!!)
}
transaction.commitAllowingStateLoss()
}
override fun onFragmentFirstVisible() {
}
override fun onFragmentResume() {
super.onFragmentResume()
if (AppConfig.fragmentClickFlag == Constant.FRAGMENT_CLICK_ONE) {
bookPresenter.getReadInfo()
}
}
override fun onDestroy() {
super.onDestroy()
IreaderApi.setReadChangeListener(null)
ZhangyueManager.onDestory()
bookPresenter.detachView()
}
override fun onReadStart() {
}
override fun onReadEnd(time: Long) {
// LogUtil.d(TAG, "onReadEnd time:" + time)
// LogUtil.d(TAG, "onReadEnd time(Int):" + (time/1000).toInt())
val seconds = (time / 1000).toInt()
// 阅读5秒以上 保存时长
if (seconds > 5) {
bookPresenter.addReadSeconds(seconds)
}
}
override fun onReadPage(time: Long) {
}
override fun readSecondsSuc(coin: Int) {
if (coin > 0) {
val bundle = Bundle()
bundle.putString(Constant.MAIN_CARRIER_TYPE, Constant.CARRIER_ZHANGYUE)
bundle.putInt(Constant.MAIN_CUR_COIN, coin)
readyGo(AwardActivity::class.java, bundle)
}
}
override fun readInfo(sumTime: Int, sumCoin: Int, readTime: Int) {
//阅读{10}分钟,奖励{xx}金币,已读{x}分钟
tvZhangContent.visibility = View.VISIBLE
if (readTime >= sumTime) {
tvZhangContent.text = "今日阅读任务已完成"
} else {
tvZhangContent.text = SpanUtils()
.append("阅读").append("${sumTime / 60}").setForegroundColor(mContext.resources.getColor(R.color.color_FF9837)).append("分钟, ")
.append("奖励").append("$sumCoin").setForegroundColor(mContext.resources.getColor(R.color.color_cb4a39)).append("金币, ")
.append("已读").append("${readTime / 60}").setForegroundColor(mContext.resources.getColor(R.color.color_FF9837)).append("分钟")
.create()
}
}
// override fun addBookShelf(p0: Bundle?) {
// TODO("Not yet implemented")
// }
//
// override fun onReadStart(p0: Bundle?) {
// TODO("Not yet implemented")
// }
//
// override fun onReadEnd(p0: Bundle?) {
// val seconds = (p0!!.getLong(IreaderApi.BOOK_TIME) / 1000).toInt()
// // 阅读5秒以上 保存时长
// if (seconds > 5) {
// bookPresenter.addReadSeconds(seconds)
// }
// }
//
// override fun onDeleteBook(p0: String?) {
// TODO("Not yet implemented")
// }
//
// override fun onReadPage(p0: Bundle?) {
// TODO("Not yet implemented")
// }
//
// override fun onChangeNight(p0: Boolean) {
// TODO("Not yet implemented")
// }
}
\ No newline at end of file
package com.mints.goodmoney.ui.fragment
import android.Manifest
import android.animation.ValueAnimator
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.widget.AdapterView
import android.widget.ImageView
import androidx.core.content.ContextCompat
import com.cretin.www.wheelsruflibrary.listener.RotateListener
import com.cretin.www.wheelsruflibrary.view.WheelSurfView
import com.daimajia.androidanimations.library.Techniques
import com.daimajia.androidanimations.library.YoYo
import com.mints.goodmoney.MintsApplication
import com.mints.goodmoney.R
import com.mints.goodmoney.common.AppConfig
import com.mints.goodmoney.common.Constant
import com.mints.goodmoney.manager.MokuManager
import com.mints.goodmoney.manager.UserManager
import com.mints.goodmoney.mvp.model.ClickTurnBean
import com.mints.goodmoney.mvp.model.TurnBean
import com.mints.goodmoney.mvp.presenters.TurnTablePresenter
import com.mints.goodmoney.mvp.views.TurnTableView
import com.mints.goodmoney.ui.activitys.*
import com.mints.goodmoney.ui.adapter.TurnTableAdapter
import com.mints.goodmoney.ui.fragment.base.BaseFragment
import com.mints.goodmoney.ui.widgets.seekbar.BubbleUtils
import com.mints.goodmoney.utils.SpanUtils
import com.mints.library.net.netstatus.NetUtils
import com.tbruyelle.rxpermissions.RxPermissions
import kotlinx.android.synthetic.main.fragment_main_turntable.*
import kotlinx.android.synthetic.main.layout_turn_btn.*
import net.grandcentrix.tray.AppPreferences
import java.util.*
import kotlin.collections.ArrayList
import kotlin.concurrent.schedule
/**
* 描述:大转盘
* 作者:孟崔广
* 时间:2021/3/22 10:20
*/
class TurnTableFragment : BaseFragment(), TurnTableView, AdapterView.OnItemClickListener {
private val turnTablePresenter by lazy { TurnTablePresenter() }
private val userManager by lazy { UserManager.getInstance() }
private val ps by lazy { AppPreferences(context) }
private var rope: YoYo.YoYoString? = null
// 转盘
private val firstColor = "#FF7C00"
private val secondColor = "#fbaa7e"
private var desList: MutableList<String> = ArrayList()
private var colorsArray: MutableList<Int> = ArrayList()
private var bitmapList: MutableList<Bitmap> = ArrayList()
private var isTurnTable = true
private var clickTurnData: ClickTurnBean? = null
private var turnTableData: TurnBean? = null
// 提现列表展示
private var drawcashList: MutableList<String> = mutableListOf()
override fun getContentViewLayoutID() = R.layout.fragment_main_turntable
override fun initViewsAndEvents() {
turnTablePresenter.attachView(this)
gvTurnTable.onItemClickListener = this
tvTurnMore.setOnClickListener {
val activity: MainActivity? = activity as MainActivity?
activity?.let {
it.turnDayTask()
}
}
if (!TextUtils.isEmpty(userManager.userID) && !TextUtils.isEmpty(MintsApplication.OAID)) {
MokuManager.initOaid(MintsApplication.OAID)
}
}
override fun onHiddenChanged(hidden: Boolean) {
if (hidden) { // 不在最前端界面显示
onPause()
} else { // 重新显示到最前端中
onResume()
}
super.onHiddenChanged(hidden)
}
override fun onResume() {
super.onResume()
if (AppConfig.fragmentClickFlag == Constant.FRAGMENT_CLICK_THREE) {
if (!TextUtils.isEmpty(userManager.userID)) {
// 通用
turnTablePresenter.getTurnMsg()
} else {
// 游客登录
turnTablePresenter.userLogin()
}
marqueeView.startFlipping()
}
}
override fun onPause() {
super.onPause()
rope?.stop()
marqueeView.stopFlipping()
}
override fun onDestroy() {
super.onDestroy()
turnTableView.setRotateListener(null)
turnTablePresenter.detachView()
}
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
turnTableData?.let {
actionPageForType(it.bottoms[position].toOtherKey, position)
}
}
override fun getTurnTableSuc(data: TurnBean) {
if (drawcashList.size == 0) {
turnTablePresenter.cashoutLeaders()
}
initTurnView(data)
}
override fun cashoutLeadersSuc() {
initMarqueeView()
}
override fun clickForTurnSuc(data: ClickTurnBean) {
if (activity == null || requireActivity().isFinishing) {
return
}
clickTurnData = data
val position = data.config.index
turnTableView.startRotate(bitmapList.size - position + 1)
}
private fun initTurnView(data: TurnBean) {
if (activity == null || requireActivity().isFinishing) {
return
}
turnTableData = data
if (data.configs.size == 0) {
showToast("网络数据异常,请联系客服")
return
}
colorsArray.clear()
desList.clear()
bitmapList.clear()
for (index in 0..data.configs.size - 1) {
//颜色
if (index % 2 == 0) {
colorsArray.add(Color.parseColor(firstColor))
} else {
colorsArray.add(Color.parseColor(secondColor))
}
//图标
if (TextUtils.equals(data.configs[index].type, "coin")) {
bitmapList.add(BitmapFactory.decodeResource(resources, R.mipmap.ic_turn_gold))
} else {
bitmapList.add(BitmapFactory.decodeResource(resources, R.mipmap.ic_turn_money))
}
//文字
desList.add(data.configs[index].title)
}
//主动旋转一下图片
bitmapList = WheelSurfView.rotateBitmaps(bitmapList) as ArrayList<Bitmap>
val build = WheelSurfView.Builder()
.setmColors(colorsArray.toTypedArray())
.setmDeses(desList.toTypedArray())
.setmIcons(bitmapList)
.setmType(1)
.setmMinTimes(5)
.setmTypeNum(data.configs.size)
.setmTextColor(Color.parseColor("#FFFFFF"))
.build()
turnTableView.setConfig(build)
//添加滚动监听
turnTableView.setRotateListener(object : RotateListener {
override fun rotateEnd(position: Int, des: String) {
isTurnTable = true
clickTurnData?.let {
val bundle = Bundle()
bundle.putInt(Constant.MAIN_CUR_COIN, it.config.count)
bundle.putString(Constant.MAIN_CARRIER_TYPE, Constant.CARRIER_CHALLENGE_TURN)
bundle.putString(Constant.MAIN_EXTRA_ID, it.turntableKey)
readyGo(AwardActivity::class.java, bundle)
}
}
override fun rotating(valueAnimator: ValueAnimator) {}
override fun rotateBefore(goImg: ImageView) {
if (!NetUtils.isNetworkConnected(context)) {
showToast("网络异常,请检测网络")
return
}
if (isTurnTable) {
isTurnTable = false
turnTablePresenter.clickForTurn()
}
}
})
tvHintTurnTable.text=data.titleMsg
tvTurnTimes.text = SpanUtils()
.append("本轮抽奖将剩余").setForegroundColor(ContextCompat.getColor(mContext, R.color.black))
.append(data.surplus.toString()).setFontSize(BubbleUtils.dp2px(28)).setForegroundColor(ContextCompat.getColor(mContext, R.color.color_E72C2B))
.append("次机会").setForegroundColor(ContextCompat.getColor(mContext, R.color.black))
.create()
gvTurnTable.setAdapter(TurnTableAdapter(activity, data.bottoms))
Timer().schedule(1000) {
activity?.runOnUiThread {
rope = YoYo.with(Techniques.Pulse).duration(1000).repeat(-1).playOn(tvTurnMore)
}
}
}
private fun actionPageForType(toOtherKey: String, position: Int) {
//0-微转,1-珊瑚下载,2-分红,3-鱼丸盒子,4-每日任务
when (toOtherKey) {
"0" -> {
if (!userManager.userIsLogin()) {
readyGo(WxLoginActivity::class.java)
return
}
shareArticle()
}
"1" -> {
if (!userManager.userIsLogin()) {
readyGo(WxLoginActivity::class.java)
return
}
readyGo(TaskCpdActivity::class.java)
}
"2" -> {
if (!userManager.userIsLogin()) {
readyGo(WxLoginActivity::class.java)
return
}
val bundle = Bundle()
bundle.putInt(Constant.WRAPPER_TYPE, Constant.WRAPPER_TYPE_FRIENDS)
readyGo(WrapperActivity::class.java, bundle)
}
"3" -> {
gotoMoku()
}
}
turnTableData?.let {
if (!TextUtils.isEmpty(it.bottoms[position].rewardTitle)) {
turnTablePresenter.addTurnToOtherMsg(toOtherKey)
}
}
}
/**
* 分享文章
*/
private fun shareArticle() {
val bundle = Bundle()
bundle.putInt(Constant.WRAPPER_TYPE, Constant.WRAPPER_TYPE_WZ)
readyGo(WrapperActivity::class.java, bundle)
}
private fun gotoMoku() {
RxPermissions(requireActivity())
.request(Manifest.permission.READ_PHONE_STATE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe { granted: Boolean ->
if (granted) {
MokuManager.gotoMoku(requireContext())
if (ps.getBoolean(Constant.MOKU_FLAG_GUIDE, true)) {
readyGo(MokuGuideActivity::class.java)
ps.put(Constant.MOKU_FLAG_GUIDE, false)
}
} else {
showMissingPermissionDialog("设备,存储")
}
}
}
private fun initMarqueeView() {
marqueeView.startWithList(drawcashList)
}
}
\ No newline at end of file
package com.mints.goodmoney.ui.fragment
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import com.ireader.ireadersdk.IreaderApi
import com.mints.goodmoney.R
import com.mints.goodmoney.common.AppConfig
import com.mints.goodmoney.common.Constant
import com.mints.goodmoney.manager.ZhangyueManager
import com.mints.goodmoney.mvp.presenters.BookPresenter
import com.mints.goodmoney.mvp.views.BookView
import com.mints.goodmoney.ui.activitys.AwardActivity
import com.mints.goodmoney.ui.fragment.base.LazyLoadBaseFragment
import com.mints.goodmoney.utils.SpanUtils
import kotlinx.android.synthetic.main.fragment_main_zy.*
/**
* 描述:掌阅书城
* 作者:孟崔广
*/
class ZhangyueFragment : LazyLoadBaseFragment(), BookView, IreaderApi.OnReadChangeListener {
private val bookPresenter by lazy { BookPresenter() }
private var bookFragment: Fragment? = null
override fun getContentViewLayoutID() = R.layout.fragment_main_zy
override fun initViewsAndEvents() {
}
override fun onFragmentFirstVisible() {
bookPresenter.attachView(this)
val transaction: FragmentTransaction = supportFragmentManager.beginTransaction()
if (bookFragment == null) {
bookFragment = IreaderApi.getNovelBookStoreFragment()
transaction.add(R.id.fragment, bookFragment!!, bookFragment!!::class.java.simpleName)
IreaderApi.setReadChangeListener(this)
} else {
transaction.show(bookFragment!!)
}
transaction.commitAllowingStateLoss()
}
override fun onFragmentResume() {
super.onFragmentResume()
if (AppConfig.fragmentClickFlag == Constant.FRAGMENT_CLICK_ONE) {
bookPresenter.getReadInfo()
}
}
override fun onDestroy() {
super.onDestroy()
IreaderApi.setReadChangeListener(null)
ZhangyueManager.onDestory()
bookPresenter.detachView()
}
override fun onReadStart() {
}
override fun onReadEnd(time: Long) {
// LogUtil.d(TAG, "onReadEnd time:" + time)
// LogUtil.d(TAG, "onReadEnd time(Int):" + (time/1000).toInt())
val seconds = (time / 1000).toInt()
// 阅读5秒以上 保存时长
if (seconds > 5) {
bookPresenter.addReadSeconds(seconds)
}
}
override fun onReadPage(time: Long) {
}
override fun readSecondsSuc(coin: Int) {
if (coin > 0) {
val bundle = Bundle()
bundle.putString(Constant.MAIN_CARRIER_TYPE, Constant.CARRIER_ZHANGYUE)
bundle.putInt(Constant.MAIN_CUR_COIN, coin)
readyGo(AwardActivity::class.java, bundle)
}
}
override fun readInfo(sumTime: Int, sumCoin: Int, readTime: Int) {
//阅读{10}分钟,奖励{xx}金币,已读{x}分钟
tvZhangContent.visibility = View.VISIBLE
if (readTime >= sumTime) {
tvZhangContent.text = "今日阅读任务已完成"
} else {
tvZhangContent.text = SpanUtils()
.append("阅读").append("${sumTime / 60}").setForegroundColor(mContext.resources.getColor(R.color.color_FF9837)).append("分钟, ")
.append("奖励").append("$sumCoin").setForegroundColor(mContext.resources.getColor(R.color.color_cb4a39)).append("金币, ")
.append("已读").append("${readTime / 60}").setForegroundColor(mContext.resources.getColor(R.color.color_FF9837)).append("分钟")
.create()
}
}
// override fun addBookShelf(p0: Bundle?) {
// }
//
// override fun onReadStart(p0: Bundle?) {
// }
//
// override fun onReadEnd(p0: Bundle?) {
// // LogUtil.d(TAG, "onReadEnd time:" + time)
//// LogUtil.d(TAG, "onReadEnd time(Int):" + (time/1000).toInt())
//
// val seconds = (p0!!.getLong(IreaderApi.BOOK_TIME).toLong() / 1000).toInt()
// // 阅读5秒以上 保存时长
// if (seconds > 5) {
// bookPresenter.addReadSeconds(seconds)
// }
// }
//
// override fun onDeleteBook(p0: String?) {
// }
//
// override fun onReadPage(p0: Bundle?) {
// }
//
// override fun onChangeNight(p0: Boolean) {
// }
}
\ No newline at end of file
......@@ -6,9 +6,9 @@
<item android:id="@android:id/background">
<shape>
<stroke
android:width="@dimen/dp_1"
android:width="1dp"
android:color="#E5E5E5" />
<corners android:radius="@dimen/dp_5" />
<corners android:radius="5dp" />
<solid android:color="#FAFAFA" />
<gradient
......@@ -26,7 +26,7 @@
<clip>
<shape android:shape="rectangle">
<solid android:color="#E9DDB6" />
<corners android:radius="@dimen/dp_5" />
<corners android:radius="5dp" />
</shape>
</clip>
</item>
......@@ -38,9 +38,9 @@
<clip>
<shape>
<stroke
android:width="@dimen/dp_1"
android:width="1dp"
android:color="#E5E5E5" />
<corners android:radius="@dimen/dp_5" />
<corners android:radius="5dp" />
<gradient
android:angle="0"
android:centerColor="#FB560C"
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 填充的颜色 -->
<solid android:color="#50ffffff" />
<!-- 设置按钮的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="10dip" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:wheelSurfView="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/bg_turntable"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_marginTop="30dp"
android:gravity="center_vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="6dp"
android:src="@mipmap/ic_voice" />
<com.sunfusheng.marqueeview.MarqueeView
android:id="@+id/marqueeView"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
app:mvAnimDuration="1000"
app:mvInterval="4000"
app:mvSingleLine="true"
app:mvTextColor="@color/color_cb4a39"
app:mvTextSize="15sp" />
</LinearLayout>
<TextView
android:id="@+id/tvHintTurnTable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="120dp"
tools:text="每日0点重置抽奖次数"
android:textColor="@color/red"
android:textSize="18sp" />
<com.cretin.www.wheelsruflibrary.view.WheelSurfView
android:id="@+id/turnTableView"
android:layout_width="330dp"
android:layout_height="330dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
wheelSurfView:typenum="-1" />
<include layout="@layout/layout_turn_btn" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<TextView
android:id="@+id/tv_turn_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="6dp"
tools:text="抽奖+1"
android:textColor="@color/red"
android:textSize="14sp" />
<ImageView
android:id="@+id/ic_turn_icon"
android:layout_width="38dp"
android:layout_height="38dp"
android:layout_gravity="center_horizontal"
android:scaleType="fitXY"
tools:src="@mipmap/ic_launcher_main" />
<TextView
android:id="@+id/tv_turn_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
tools:text="搜索赚"
android:textColor="@color/red"
android:textSize="14sp" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@drawable/shape_turn_btn"
android:elevation="18dp"
android:orientation="vertical"
android:paddingTop="4dp"
android:paddingBottom="10dp">
<TextView
android:id="@+id/tvTurnTimes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textColor="@color/black"
android:layout_marginBottom="6dp"
android:textSize="12sp" />
<com.mints.goodmoney.ui.widgets.ExpandableGridView
android:id="@+id/gvTurnTable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="80dp"
android:divider="@null"
android:dividerHeight="10pt"
android:elevation="6dip"
android:listSelector="#00000000"
android:numColumns="4"
android:scrollbars="none"
android:stretchMode="spacingWidthUniform" />
<TextView
android:id="@+id/tvTurnMore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:drawableTop="@mipmap/ic_arrow_down"
android:drawablePadding="4dp"
android:text="点击获取更多奖励"
android:textColor="@color/red"
android:textSize="14sp"></TextView>
</LinearLayout>
\ No newline at end of file
include ':demo'
include ':app'
include ':shareSdkLib'
\ No newline at end of file
include ':shareSdkLib'
include ':wheelsruflibrary'
\ No newline at end of file
apply plugin: 'com.android.library'
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
package com.cretin.www.wheelsruflibrary;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith( AndroidJUnit4.class )
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.cretin.www.wheelsruflibrary.test", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cretin.www.wheelsruflibrary"/>
package com.cretin.www.wheelsruflibrary.listener;
import android.animation.ValueAnimator;
import android.widget.ImageView;
/**
* Created by cretin on 2017/12/27.
* 用于回调动画过程和结果
*/
public interface RotateListener {
/**
* 动画结束 返回当前位置 注意 位置是最上面是1 然后依次逆时针递增
*
* @param position
* @param des 所指分区文字描述
*/
void rotateEnd(int position, String des);
/**
* 动画进行中 返回动画中间量
*
* @param valueAnimator
*/
void rotating(ValueAnimator valueAnimator);
/**
* 点击了按钮 但是没有旋转 调用者可以在这里处理一些逻辑 比如弹出对话框确定用户是否要抽奖
*
* @param goImg
*/
void rotateBefore(ImageView goImg);
}
package com.cretin.www.wheelsruflibrary.view;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.cretin.www.wheelsruflibrary.R;
import com.cretin.www.wheelsruflibrary.listener.RotateListener;
import java.util.ArrayList;
import java.util.List;
/**
* Created by cretin on 2017/12/26.
*/
public class WheelSurfPanView extends View {
private Context mContext;
//记录视图的大小
private int mWidth;
//记录当前有几个分类
private Paint mPaint;
//文字画笔
private Paint mTextPaint;
//圆环图片
private Bitmap mYuanHuan;
//大图片
private Bitmap mMain;
//中心点横坐标
private int mCenter;
//绘制扇形的半径 减掉50是为了防止边界溢出 具体效果你自己注释掉-50自己测试
private int mRadius;
//每一个扇形的角度
private float mAngle;
private List<Bitmap> mListBitmap;
//动画回调监听
private RotateListener rotateListener;
public RotateListener getRotateListener() {
return rotateListener;
}
public void setRotateListener(RotateListener rotateListener) {
this.rotateListener = rotateListener;
}
public WheelSurfPanView(Context context) {
super(context);
init(context, null);
}
public WheelSurfPanView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public WheelSurfPanView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
//当前类型 1 自定义模式 2 暴力模式
private int mType;
//最低圈数 默认值3 也就是说每次旋转都会最少转3圈
private int mMinTimes;
//分类数量 如果数量为负数 通过代码设置样式
private int mTypeNum = 6;
//每个扇形旋转的时间
private int mVarTime = 75;
//文字描述集合
private String[] mDeses;
//自定义图标集合
private Integer[] mIcons;
//背景颜色
private Integer[] mColors;
//整个旋转图的背景 只有类型为2时才需要
private Integer mMainImgRes;
//圆环的图片引用
private Integer mHuanImgRes;
//文字大小
private float mTextSize;
//文字颜色
private int mTextColor;
public void setmType(int mType) {
this.mType = mType;
}
public void setmMinTimes(int mMinTimes) {
this.mMinTimes = mMinTimes;
}
public void setmVarTime(int mVarTime) {
this.mVarTime = mVarTime;
}
public void setmTypeNum(int mTypeNum) {
this.mTypeNum = mTypeNum;
}
public void setmDeses(String[] mDeses) {
this.mDeses = mDeses;
}
public void setmIcons(List<Bitmap> mIcons) {
this.mListBitmap = mIcons;
}
public void setmColors(Integer[] mColors) {
this.mColors = mColors;
}
public void setmMainImgRes(Integer mMainImgRes) {
this.mMainImgRes = mMainImgRes;
}
public void setmHuanImgRes(Integer mHuanImgRes) {
this.mHuanImgRes = mHuanImgRes;
}
public void setmTextSize(float mTextSize) {
this.mTextSize = mTextSize;
}
public void setmTextColor(int mTextColor) {
this.mTextColor = mTextColor;
}
private void init(Context context, AttributeSet attrs) {
mContext = context;
setBackgroundColor(Color.TRANSPARENT);
if ( attrs != null ) {
//获得这个控件对应的属性。
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.wheelSurfView);
try {
mType = typedArray.getInteger(R.styleable.wheelSurfView_type, 1);
mVarTime = typedArray.getInteger(R.styleable.wheelSurfView_vartime, 0);
mMinTimes = typedArray.getInteger(R.styleable.wheelSurfView_minTimes, 3);
mTypeNum = typedArray.getInteger(R.styleable.wheelSurfView_typenum, 0);
if ( mTypeNum == -1 ) {
//用代码去配置这些参数
} else {
if ( mVarTime == 0 )
mVarTime = 75;
if ( mTypeNum == 0 )
throw new RuntimeException("找不到分类数量mTypeNum");
//每一个扇形的角度
mAngle = ( float ) (360.0 / mTypeNum);
if ( mType == 1 ) {
mHuanImgRes = typedArray.getResourceId(R.styleable.wheelSurfView_huanImg, 0);
if ( mHuanImgRes == 0 )
mYuanHuan = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.yuanhuan);
else {
mYuanHuan = BitmapFactory.decodeResource(mContext.getResources(), mHuanImgRes);
}
//文字大小
mTextSize = typedArray.getDimension(R.styleable.wheelSurfView_textSize, 14 * getScale());
//文字颜色 默认粉红色
mTextColor = typedArray.getColor(R.styleable.wheelSurfView_textColor, Color.parseColor("#ff00ff"));
//描述
int nameArray = typedArray.getResourceId(R.styleable.wheelSurfView_deses, -1);
if ( nameArray == -1 ) throw new RuntimeException("找不到描述");
mDeses = context.getResources().getStringArray(nameArray);
//图片
int iconArray = typedArray.getResourceId(R.styleable.wheelSurfView_icons, -1);
if ( iconArray == -1 ) throw new RuntimeException("找不到分类的图片资源");
String[] iconStrs = context.getResources().getStringArray(iconArray);
List<Integer> iconLists = new ArrayList<>();
for ( int i = 0; i < iconStrs.length; i++ ) {
iconLists.add(context.getResources().getIdentifier(iconStrs[i], "mipmap", context.getPackageName()));
}
mIcons = iconLists.toArray(new Integer[iconLists.size()]);
//颜色
int colorArray = typedArray.getResourceId(R.styleable.wheelSurfView_colors, -1);
if ( colorArray == -1 ) throw new RuntimeException("找不到背景颜色");
String[] colorStrs = context.getResources().getStringArray(colorArray);
if ( mDeses == null || mIcons == null || colorStrs == null )
throw new RuntimeException("找不到描述或图片或背景颜色资源");
if ( mDeses.length != mTypeNum || mIcons.length != mTypeNum || colorStrs.length != mTypeNum )
throw new RuntimeException("资源或描述或背景颜色的长度和mTypeNum不一致");
mColors = new Integer[mTypeNum];
//分析背景颜色
for ( int i = 0; i < colorStrs.length; i++ ) {
try {
mColors[i] = Color.parseColor(colorStrs[i]);
} catch ( Exception e ) {
throw new RuntimeException("颜色值有误");
}
}
//加载分类图片 存放图片的集合
mListBitmap = new ArrayList<>();
for ( int i = 0; i < mTypeNum; i++ ) {
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), mIcons[i]);
int ww = bitmap.getWidth();
int hh = bitmap.getHeight();
// 定义矩阵对象
Matrix matrix = new Matrix();
// 缩放原图
matrix.postScale(1f, 1f);
// 向左旋转45度,参数为正则向右旋转
matrix.postRotate(mAngle * i);
//bmp.getWidth(), 500分别表示重绘后的位图宽高
Bitmap dstbmp = Bitmap.createBitmap(bitmap, 0, 0, ww, hh,
matrix, true);
mListBitmap.add(dstbmp);
}
//文字画笔
mTextPaint = new Paint();
//设置填充样式
mTextPaint.setStyle(Paint.Style.FILL);
//设置抗锯齿
mTextPaint.setAntiAlias(true);
//设置边界模糊
mTextPaint.setDither(true);
//设置画笔颜色
mTextPaint.setColor(mTextColor);
//设置字体大小
mTextPaint.setTextSize(mTextSize);
} else if ( mType == 2 ) {
mMainImgRes = typedArray.getResourceId(R.styleable.wheelSurfView_mainImg, 0);
//直接大图
if ( mMainImgRes == 0 )
throw new RuntimeException("类型为2必须要传大图mMainImgRes");
mMain = BitmapFactory.decodeResource(mContext.getResources(), mMainImgRes);
} else {
throw new RuntimeException("类型type错误");
}
}
} finally { //回收这个对象
typedArray.recycle();
}
}
//其他画笔
mPaint = new Paint();
//设置填充样式
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
//设置抗锯齿
mPaint.setAntiAlias(true);
//设置边界模糊
mPaint.setDither(true);
}
//目前的角度
private float currAngle = 0;
//记录上次的位置
private int lastPosition;
/**
* 开始转动
* pos 位置 1 开始 这里的位置上是按照逆时针递增的 比如当前指的那个选项是第一个 那么他左边的那个是第二个 以此类推
*/
public void startRotate(final int pos) {
//最低圈数是mMinTimes圈
int newAngle = ( int ) (360 * mMinTimes + (pos - 1) * mAngle + currAngle - (lastPosition == 0 ? 0 : ((lastPosition - 1) * mAngle)));
//计算目前的角度划过的扇形份数
int num = ( int ) ((newAngle - currAngle) / mAngle);
ObjectAnimator anim = ObjectAnimator.ofFloat(WheelSurfPanView.this, "rotation", currAngle, newAngle);
currAngle = newAngle;
lastPosition = pos;
// 动画的持续时间,执行多久?
anim.setDuration(num * mVarTime);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//将动画的过程态回调给调用者
if ( rotateListener != null )
rotateListener.rotating(animation);
}
});
final float[] f = {0};
anim.setInterpolator(new TimeInterpolator() {
@Override
public float getInterpolation(float t) {
float f1 = ( float ) (Math.cos((t + 1) * Math.PI) / 2.0f) + 0.5f;
Log.e("HHHHHHHh", "" + t + " " + (f[0] - f1));
f[0] = ( float ) (Math.cos((t + 1) * Math.PI) / 2.0f) + 0.5f;
return f[0];
}
});
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
//当旋转结束的时候回调给调用者当前所选择的内容
if ( rotateListener != null ) {
if ( mType == 1 ) {
//去空格和前后空格后输出
String des = mDeses[(mTypeNum - pos + 1) %
mTypeNum].trim().replaceAll(" ", "");
rotateListener.rotateEnd(pos, des);
} else {
rotateListener.rotateEnd(pos, "");
}
}
}
});
// 正式开始启动执行动画
anim.start();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//视图是个正方形的 所以有宽就足够了 默认值是500 也就是WRAP_CONTENT的时候
int desiredWidth = 800;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int width;
//Measure Width
if ( widthMode == MeasureSpec.EXACTLY ) {
//Must be this size
width = widthSize;
} else if ( widthMode == MeasureSpec.AT_MOST ) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
} else {
//Be whatever you want
width = desiredWidth;
}
//将测得的宽度保存起来
mWidth = width;
mCenter = mWidth / 2;
//绘制扇形的半径 减掉50是为了防止边界溢出 具体效果你自己注释掉-50自己测试
mRadius = mWidth / 2 - 50;
//MUST CALL THIS
setMeasuredDimension(width, width);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if ( mTypeNum == -1 ) {
//先不管
} else {
if ( mType == 1 ) {
// 计算初始角度
// 从最上面开始绘制扇形会好看一点
float startAngle = -mAngle / 2 - 90;
final int paddingLeft = getPaddingLeft();
final int paddingRight = getPaddingRight();
final int paddingTop = getPaddingTop();
final int paddingBottom = getPaddingBottom();
int width = getWidth() - paddingLeft - paddingRight;
int height = getHeight() - paddingTop - paddingBottom;
for ( int i = 0; i < mTypeNum; i++ ) {
//设置绘制时画笔的颜色
mPaint.setColor(mColors[i]);
//画一个扇形
RectF rect = new RectF(mCenter - mRadius, mCenter - mRadius, mCenter
+ mRadius, mCenter + mRadius);
canvas.drawArc(rect, startAngle, mAngle, true, mPaint);
mTextPaint.setColor(mTextColor);
drawText(startAngle, mDeses[i], mRadius, mTextPaint, canvas);
int imgWidth = mRadius / 3;
int w = ( int ) (Math.abs(Math.cos(Math.toRadians(Math.abs(180 - mAngle * i)))) *
imgWidth + imgWidth * Math.abs(Math.sin(Math.toRadians(Math.abs(180 - mAngle * i)))));
int h = ( int ) (Math.abs(Math.sin(Math.toRadians(Math.abs(180 - mAngle * i)))) *
imgWidth + imgWidth * Math.abs(Math.cos(Math.toRadians(Math.abs(180 - mAngle * i)))));
float angle = ( float ) Math.toRadians(startAngle + mAngle / 2);
//确定图片在圆弧中 中心点的位置
float x = ( float ) (width / 2 + (mRadius / 2 + mRadius / 12) * Math.cos(angle));
float y = ( float ) (height / 2 + (mRadius / 2 + mRadius / 12) * Math.sin(angle));
// 确定绘制图片的位置
RectF rect1 = new RectF(x - w / 2, y - h / 2, x + w / 2, y + h / 2);
canvas.drawBitmap(mListBitmap.get(i), null, rect1, null);
//重置开始角度
startAngle = startAngle + mAngle;
}
//最后绘制圆环
Rect mDestRect = new Rect(0, 0, mWidth, mWidth);
canvas.drawBitmap(mYuanHuan, null, mDestRect, mPaint);
} else {
//大圆盘
Rect mDestRect = new Rect(0, 0, mWidth, mWidth);
canvas.drawBitmap(mMain, null, mDestRect, mPaint);
}
}
}
//绘制文字
private void drawText(float startAngle, String string, int radius, Paint textPaint, Canvas canvas) {
//创建绘制路径
Path circlePath = new Path();
//范围也是整个圆盘
RectF rect = new RectF(mCenter - radius, mCenter - radius, mCenter
+ radius, mCenter + radius);
//给定扇形的范围
circlePath.addArc(rect, startAngle, mAngle);
//圆弧的水平偏移
float textWidth = textPaint.measureText(string);
//圆弧的垂直偏移
float hOffset = ( float ) (Math.sin(mAngle / 2 / 180 * Math.PI) * radius) - textWidth / 2;
//绘制文字
canvas.drawTextOnPath(string, circlePath, hOffset, radius / 4, textPaint);
}
//再一次onDraw
public void show() {
//做最后的准备工作 检查数据是否合理
if ( mType == 1 ) {
if ( mHuanImgRes == null || mHuanImgRes == 0 )
mYuanHuan = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.yuanhuan);
else {
mYuanHuan = BitmapFactory.decodeResource(mContext.getResources(), mHuanImgRes);
}
//文字大小
if ( mTextSize == 0 )
mTextSize = 14 * getScale();
//文字颜色 默认粉红色
if ( mTextColor == 0 )
mTextColor = Color.parseColor("#ff00ff");
if ( mListBitmap.size() != mDeses.length || mListBitmap.size() != mColors.length
|| mDeses.length != mColors.length ) {
throw new RuntimeException("Icons数量和Deses和Colors三者数量必须与mTypeNum一致");
}
} else {
//直接大图
if ( mMainImgRes == null || mMainImgRes == 0 )
throw new RuntimeException("类型为2必须要传大图mMainImgRes");
mMain = BitmapFactory.decodeResource(mContext.getResources(), mMainImgRes);
}
if ( mTextPaint == null ) {
//文字画笔
mTextPaint = new Paint();
//设置填充样式
mTextPaint.setStyle(Paint.Style.FILL);
//设置抗锯齿
mTextPaint.setAntiAlias(true);
//设置边界模糊
mTextPaint.setDither(true);
//设置画笔颜色
mTextPaint.setColor(mTextColor);
//设置字体大小
mTextPaint.setTextSize(mTextSize);
}
if ( mTypeNum != 0 )
mAngle = ( float ) (360.0 / mTypeNum);
if ( mVarTime == 0 )
mVarTime = 75;
//重绘
invalidate();
}
private float getScale() {
TextView textView = new TextView(mContext);
textView.setTextSize(1);
return textView.getTextSize();
}
}
package com.cretin.www.wheelsruflibrary.view;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.cretin.www.wheelsruflibrary.R;
import com.cretin.www.wheelsruflibrary.listener.RotateListener;
import java.util.ArrayList;
import java.util.List;
/**
* Created by cretin on 2017/12/26.
*/
public class WheelSurfView extends RelativeLayout {
//当前的圆盘VIew
private WheelSurfPanView mWheelSurfPanView;
//Context
private Context mContext;
//开始按钮
private ImageView mStart;
//动画回调监听
private RotateListener rotateListener;
public void setRotateListener(RotateListener rotateListener) {
mWheelSurfPanView.setRotateListener(rotateListener);
this.rotateListener = rotateListener;
}
public WheelSurfView(Context context) {
super(context);
init(context, null);
}
public WheelSurfView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public WheelSurfView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
//开始抽奖的图标
private Integer mGoImgRes;
private void init(Context context, AttributeSet attrs) {
mContext = context;
if ( attrs != null ) {
//获得这个控件对应的属性。
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.wheelSurfView);
try {
mGoImgRes = typedArray.getResourceId(R.styleable.wheelSurfView_goImg, 0);
} finally { //回收这个对象
typedArray.recycle();
}
}
//添加圆盘视图
mWheelSurfPanView = new WheelSurfPanView(mContext, attrs);
RelativeLayout.LayoutParams layoutParams =
new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
mWheelSurfPanView.setLayoutParams(layoutParams);
addView(mWheelSurfPanView);
//添加开始按钮
mStart = new ImageView(mContext);
//如果用户没有设置自定义的图标就使用默认的
if ( mGoImgRes == 0 ) {
mStart.setImageResource(R.mipmap.node);
} else {
mStart.setImageResource(mGoImgRes);
}
//给图片设置LayoutParams
RelativeLayout.LayoutParams llStart =
new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
llStart.addRule(RelativeLayout.CENTER_IN_PARENT);
mStart.setLayoutParams(llStart);
addView(mStart);
mStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//调用此方法是将主动权交个调用者 由调用者调用开始旋转的方法
if ( rotateListener != null )
rotateListener.rotateBefore(( ImageView ) v);
}
});
}
public void setConfig(Builder builder) {
if ( builder.mColors != null )
mWheelSurfPanView.setmColors(builder.mColors);
if ( builder.mDeses != null )
mWheelSurfPanView.setmDeses(builder.mDeses);
if ( builder.mHuanImgRes != 0 )
mWheelSurfPanView.setmHuanImgRes(builder.mHuanImgRes);
if ( builder.mIcons != null )
mWheelSurfPanView.setmIcons(builder.mIcons);
if ( builder.mMainImgRes != 0 )
mWheelSurfPanView.setmMainImgRes(builder.mMainImgRes);
if ( builder.mMinTimes != 0 )
mWheelSurfPanView.setmMinTimes(builder.mMinTimes);
if ( builder.mTextColor != 0 )
mWheelSurfPanView.setmTextColor(builder.mTextColor);
if ( builder.mTextSize != 0 )
mWheelSurfPanView.setmTextSize(builder.mTextSize);
if ( builder.mType != 0 )
mWheelSurfPanView.setmType(builder.mType);
if ( builder.mVarTime != 0 )
mWheelSurfPanView.setmVarTime(builder.mVarTime);
if ( builder.mTypeNum != 0 )
mWheelSurfPanView.setmTypeNum(builder.mTypeNum);
mWheelSurfPanView.show();
}
/**
* 开始旋转
*
* @param pisition 旋转最终的位置 注意 从1 开始 而且是逆时针递增
*/
public void startRotate(int pisition) {
if ( mWheelSurfPanView != null ) {
mWheelSurfPanView.startRotate(pisition);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//视图是个正方形的 所以有宽就足够了 默认值是500 也就是WRAP_CONTENT的时候
setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec));
// Children are just made to fill our space.
final int childWidthSize = getMeasuredWidth();
//高度和宽度一样
heightMeasureSpec = widthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidthSize, MeasureSpec.EXACTLY);
//onMeasure调用获取到当前视图大小之后,
// 手动按照一定的比例计算出中间开始按钮的大小,
// 再设置给那个按钮,免得造成用户传的图片不合适之后显示贼难看
// 只设置一次
if ( isFirst ) {
isFirst = !isFirst;
//获取中间按钮的大小
ViewTreeObserver vto = mStart.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@TargetApi( Build.VERSION_CODES.KITKAT )
@Override
public void onGlobalLayout() {
mStart.getViewTreeObserver().removeGlobalOnLayoutListener(this);
float w = mStart.getMeasuredWidth();
float h = mStart.getMeasuredHeight();
//计算新的大小 默认为整个大小最大值的0.17 至于为什么是0.17 我只想说我乐意。。。。
int newW = ( int ) ((( float ) childWidthSize) * 0.17);
int newH = ( int ) ((( float ) childWidthSize) * 0.17 * h / w);
ViewGroup.LayoutParams layoutParams = mStart.getLayoutParams();
layoutParams.width = newW;
layoutParams.height = newH;
mStart.setLayoutParams(layoutParams);
}
});
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
//记录当前是否是第一次回调onMeasure
private boolean isFirst = true;
//建造者模式
public static final class Builder {
//当前类型 1 自定义模式 2 暴力模式
private int mType = 0;
//最低圈数 默认值3 也就是说每次旋转都会最少转3圈
private int mMinTimes = 0;
//分类数量 如果数量为负数 通过代码设置样式
private int mTypeNum = 0;
//每个扇形旋转的时间
private int mVarTime = 0;
//文字描述集合
private String[] mDeses;
//自定义图标集合
private List<Bitmap> mIcons;
//背景颜色
private Integer[] mColors;
//整个旋转图的背景 只有类型为2时才需要
private Integer mMainImgRes = 0;
//GO图标
private Integer mGoImgRes = 0;
//圆环的图片引用
private Integer mHuanImgRes = 0;
//文字大小
private float mTextSize = 0;
//文字颜色
private int mTextColor = 0;
public final WheelSurfView.Builder setmType(int mType) {
this.mType = mType;
return this;
}
public final WheelSurfView.Builder setmTypeNum(int mTypeNum) {
this.mTypeNum = mTypeNum;
return this;
}
public final WheelSurfView.Builder setmGoImgRes(int mGoImgRes) {
this.mGoImgRes = mGoImgRes;
return this;
}
public final WheelSurfView.Builder setmMinTimes(int mMinTimes) {
this.mMinTimes = mMinTimes;
return this;
}
public final WheelSurfView.Builder setmVarTime(int mVarTime) {
this.mVarTime = mVarTime;
return this;
}
public final WheelSurfView.Builder setmDeses(String[] mDeses) {
this.mDeses = mDeses;
return this;
}
public final WheelSurfView.Builder setmIcons(List<Bitmap> mIcons) {
this.mIcons = mIcons;
return this;
}
public final WheelSurfView.Builder setmColors(Integer[] mColors) {
this.mColors = mColors;
return this;
}
public final WheelSurfView.Builder setmMainImgRes(Integer mMainImgRes) {
this.mMainImgRes = mMainImgRes;
return this;
}
public final WheelSurfView.Builder setmHuanImgRes(Integer mHuanImgRes) {
this.mHuanImgRes = mHuanImgRes;
return this;
}
public final WheelSurfView.Builder setmTextSize(float mTextSize) {
this.mTextSize = mTextSize;
return this;
}
public final WheelSurfView.Builder setmTextColor(int mTextColor) {
this.mTextColor = mTextColor;
return this;
}
public final Builder build() {
return this;
}
}
//旋转图片
public static List<Bitmap> rotateBitmaps(List<Bitmap> source) {
float mAngle = ( float ) (360.0 / source.size());
List<Bitmap> result = new ArrayList<>();
for ( int i = 0; i < source.size(); i++ ) {
Bitmap bitmap = source.get(i);
int ww = bitmap.getWidth();
int hh = bitmap.getHeight();
// 定义矩阵对象
Matrix matrix = new Matrix();
// 缩放原图
matrix.postScale(1f, 1f);
// 向左旋转45度,参数为正则向右旋转
matrix.postRotate(mAngle * i);
//bmp.getWidth(), 500分别表示重绘后的位图宽高
Bitmap dstbmp = Bitmap.createBitmap(bitmap, 0, 0, ww, hh,
matrix, true);
result.add(dstbmp);
}
return result;
}
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="wheelSurfView">
<!--类型 根据类型来加载资源 1 默认类型 用户需要提供文字和图片 2 暴力模式 用户只需要提供一张圆形的用来旋转的图片-->
<attr name="type" format="integer"/>
<!--最低圈数 默认值3 也就是说每次旋转都会最少转3圈-->
<attr name="minTimes" format="integer"/>
<!--扇形的数量 也就是奖品的份数-->
<attr name="typenum" format="integer"/>
<!--每一个扇形旋转消耗的时间-->
<attr name="vartime" format="integer"/>
<!--类型为1的时候 需要提供每个扇形上面的文字描述 长度必须和typenum一致-->
<attr name="deses" format="reference"/>
<!--类型为1的时候 需要提供每个扇形上面的图片展示 长度必须和typenum一致-->
<attr name="icons" format="reference"/>
<!--类型为1的时候 需要提供每个扇形背景颜色 长度必须和typenum一致-->
<attr name="colors" format="reference"/>
<!--中间图片的引用 有默认值 不填则使用默认值-->
<attr name="goImg" format="reference"/>
<!--圆环的图片引用 有默认值 不填则使用默认值-->
<attr name="huanImg" format="reference"/>
<!--如果类型为2 此值必填-->
<attr name="mainImg" format="reference"/>
<!--文字大小-->
<attr name="textSize" format="dimension"/>
<!--文字颜色-->
<attr name="textColor" format="reference|color"/>
</declare-styleable>
</resources>
\ No newline at end of file
<resources>
<string name="app_name">WheelSrufLibrary</string>
</resources>
package com.cretin.www.wheelsruflibrary;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment