{
+
+ public ListDropDownAdapter(Context context, String[] data) {
+ super(context, data);
+ }
+
+ @Override
+ protected ViewHolder newViewHolder(View convertView) {
+ return new ViewHolder(convertView);
+ }
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.adapter_drop_down_list_item;
+ }
+
+ @Override
+ protected void convert(ViewHolder holder, String item, int position) {
+ holder.mText.setText(item);
+ if (mSelectPosition != -1) {
+ if (mSelectPosition == position) {
+ holder.mText.setSelected(true);
+ holder.mText.setBackgroundResource(R.color.check_bg);
+ } else {
+ holder.mText.setSelected(false);
+ holder.mText.setBackgroundResource(R.color.white);
+ }
+ }
+ }
+
+ static class ViewHolder {
+ @BindView(R.id.text)
+ TextView mText;
+
+ ViewHolder(View view) {
+ ButterKnife.bind(this, view);
+
+ mText.setGravity(Gravity.CENTER);
+ }
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/base/BaseActivity.java b/app/src/main/java/com/xuexiang/xuidemo/base/BaseActivity.java
index 4a4d4eb7..d3a5523a 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/base/BaseActivity.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/base/BaseActivity.java
@@ -50,7 +50,8 @@ protected void attachBaseContext(Context newBase) {
@Override
protected void onCreate(Bundle savedInstanceState) {
- Utils.initTheme(this);
+ initAppTheme();
+ initStatusBarStyle();
super.onCreate(savedInstanceState);
mUnbinder = ButterKnife.bind(this);
@@ -63,6 +64,20 @@ protected void onCreate(Bundle savedInstanceState) {
}
}
+ /**
+ * 初始化应用的主题
+ */
+ protected void initAppTheme() {
+ Utils.initTheme(this);
+ }
+
+ /**
+ * 初始化状态栏的样式
+ */
+ protected void initStatusBarStyle() {
+
+ }
+
/**
* @return 是否支持侧滑返回
*/
diff --git a/app/src/main/java/com/xuexiang/xuidemo/base/webview/MiddlewareWebViewClient.java b/app/src/main/java/com/xuexiang/xuidemo/base/webview/MiddlewareWebViewClient.java
index 1b6dbfa6..4a254bd9 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/base/webview/MiddlewareWebViewClient.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/base/webview/MiddlewareWebViewClient.java
@@ -16,9 +16,6 @@
package com.xuexiang.xuidemo.base.webview;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
@@ -30,12 +27,9 @@
import com.just.agentweb.core.client.MiddlewareWebClientBase;
import com.xuexiang.xui.utils.ResUtils;
-import com.xuexiang.xui.widget.dialog.DialogLoader;
import com.xuexiang.xuidemo.R;
-import com.xuexiang.xuidemo.utils.XToastUtils;
-import com.xuexiang.xutil.XUtil;
-import java.net.URISyntaxException;
+import static com.xuexiang.xuidemo.base.webview.WebViewInterceptDialog.APP_LINK_HOST;
/**
* 【网络请求、加载】
@@ -60,7 +54,7 @@
*
*
* 中断中间件的执行, 删除super.methodName(...) 这行即可
- *
+ *
* 这里主要是做去广告的工作
*/
public class MiddlewareWebViewClient extends MiddlewareWebClientBase {
@@ -131,10 +125,6 @@ public static boolean hasAd(String url) {
return false;
}
- public static final String APP_LINK_HOST = "xuexiangjys.club";
- public static final String APP_LINK_ACTION = "com.xuexiang.xui.applink";
-
-
/**
* 根据url的scheme处理跳转第三方app的业务
*/
@@ -149,7 +139,7 @@ private boolean shouldOverrideUrlLoadingByApp(WebView webView, final String url)
}
}
- WebViewTipDialog.show(url);
+ WebViewInterceptDialog.show(url);
return true;
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/base/webview/WebLayout.java b/app/src/main/java/com/xuexiang/xuidemo/base/webview/WebLayout.java
index 297eae7c..296b00d4 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/base/webview/WebLayout.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/base/webview/WebLayout.java
@@ -17,14 +17,15 @@
package com.xuexiang.xuidemo.base.webview;
import android.app.Activity;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.webkit.WebView;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import com.just.agentweb.widget.IWebLayout;
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
+import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.xuexiang.xuidemo.R;
/**
@@ -35,19 +36,18 @@
*/
public class WebLayout implements IWebLayout {
- private final TwinklingRefreshLayout mTwinklingRefreshLayout;
+ private final SmartRefreshLayout mSmartRefreshLayout;
private WebView mWebView;
public WebLayout(Activity activity) {
- mTwinklingRefreshLayout = (TwinklingRefreshLayout) LayoutInflater.from(activity).inflate(R.layout.fragment_twk_web, null);
- mTwinklingRefreshLayout.setPureScrollModeOn();
- mWebView = mTwinklingRefreshLayout.findViewById(R.id.webView);
+ mSmartRefreshLayout = (SmartRefreshLayout) LayoutInflater.from(activity).inflate(R.layout.fragment_pulldown_web, null);
+ mWebView = mSmartRefreshLayout.findViewById(R.id.webView);
}
@NonNull
@Override
public ViewGroup getLayout() {
- return mTwinklingRefreshLayout;
+ return mSmartRefreshLayout;
}
@Nullable
@@ -56,5 +56,4 @@ public WebView getWebView() {
return mWebView;
}
-
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/base/webview/WebViewTipDialog.java b/app/src/main/java/com/xuexiang/xuidemo/base/webview/WebViewInterceptDialog.java
similarity index 88%
rename from app/src/main/java/com/xuexiang/xuidemo/base/webview/WebViewTipDialog.java
rename to app/src/main/java/com/xuexiang/xuidemo/base/webview/WebViewInterceptDialog.java
index 189de67c..720d230c 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/base/webview/WebViewTipDialog.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/base/webview/WebViewInterceptDialog.java
@@ -35,21 +35,25 @@
import java.net.URISyntaxException;
-import static com.xuexiang.xuidemo.base.webview.MiddlewareWebViewClient.APP_LINK_ACTION;
-import static com.xuexiang.xuidemo.base.webview.MiddlewareWebViewClient.APP_LINK_HOST;
-
/**
* WebView拦截提示
*
* @author xuexiang
* @since 2019-10-21 9:51
*/
-public class WebViewTipDialog extends AppCompatActivity implements DialogInterface.OnDismissListener {
+public class WebViewInterceptDialog extends AppCompatActivity implements DialogInterface.OnDismissListener {
- private static final String KEY_INTERCEPT_URL = "KEY_INTERCEPT_URL";
+ private static final String KEY_INTERCEPT_URL = "key_intercept_url";
+ public static final String APP_LINK_HOST = "xuexiangjys.club";
+ public static final String APP_LINK_ACTION = "com.xuexiang.xui.applink";
+ /**
+ * 显示WebView拦截提示
+ *
+ * @param url
+ */
public static void show(String url) {
- ActivityUtils.startActivity(WebViewTipDialog.class, KEY_INTERCEPT_URL, url);
+ ActivityUtils.startActivity(WebViewInterceptDialog.class, KEY_INTERCEPT_URL, url);
}
@Override
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/AboutFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/AboutFragment.java
index 5bd370d1..2ec3e9b2 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/AboutFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/AboutFragment.java
@@ -79,6 +79,7 @@ public void onClick(View v) {
Utils.checkUpdate(getContext(), true);
}
})
+ .addItemView(mAboutGroupListView.createItemView(getResources().getString(R.string.about_item_add_qq_group)), v -> Utils.goWeb(getContext(), getString(R.string.url_add_qq_group)))
.addTo(mAboutGroupListView);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy", Locale.CHINA);
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/LoginFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/LoginFragment.java
new file mode 100644
index 00000000..42d77943
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/LoginFragment.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment;
+
+import android.graphics.Color;
+import android.view.View;
+
+import com.xuexiang.xaop.annotation.SingleClick;
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xpage.enums.CoreAnim;
+import com.xuexiang.xui.utils.CountDownButtonHelper;
+import com.xuexiang.xui.utils.ResUtils;
+import com.xuexiang.xui.widget.actionbar.TitleBar;
+import com.xuexiang.xui.widget.button.roundbutton.RoundButton;
+import com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.activity.MainActivity;
+import com.xuexiang.xuidemo.base.BaseFragment;
+import com.xuexiang.xuidemo.utils.TokenUtils;
+import com.xuexiang.xuidemo.utils.XToastUtils;
+import com.xuexiang.xutil.app.ActivityUtils;
+import com.xuexiang.xutil.common.RandomUtils;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+
+/**
+ * 登录页面
+ *
+ * @author xuexiang
+ * @since 2019-11-17 22:15
+ */
+@Page(anim = CoreAnim.none)
+public class LoginFragment extends BaseFragment {
+
+ @BindView(R.id.et_phone_number)
+ MaterialEditText etPhoneNumber;
+ @BindView(R.id.et_verify_code)
+ MaterialEditText etVerifyCode;
+ @BindView(R.id.btn_get_verify_code)
+ RoundButton btnGetVerifyCode;
+
+ private CountDownButtonHelper mCountDownHelper;
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.fragment_login;
+ }
+
+ @Override
+ protected TitleBar initTitle() {
+ TitleBar titleBar = super.initTitle()
+ .setImmersive(true);
+ titleBar.setBackgroundColor(Color.TRANSPARENT);
+ titleBar.setTitle("");
+ titleBar.setLeftImageDrawable(ResUtils.getVectorDrawable(getContext(), R.drawable.ic_login_close));
+ return titleBar;
+ }
+
+ @Override
+ protected void initViews() {
+ mCountDownHelper = new CountDownButtonHelper(btnGetVerifyCode, 60);
+
+ }
+
+ @SingleClick
+ @OnClick({R.id.btn_get_verify_code, R.id.btn_login, R.id.tv_other_login, R.id.tv_forget_password, R.id.tv_user_protocol, R.id.tv_privacy_protocol})
+ public void onViewClicked(View view) {
+ switch (view.getId()) {
+ case R.id.btn_get_verify_code:
+ if (etPhoneNumber.validate()) {
+ getVerifyCode(etPhoneNumber.getEditValue());
+ }
+ break;
+ case R.id.btn_login:
+ if (etPhoneNumber.validate()) {
+ if (etVerifyCode.validate()) {
+ loginByVerifyCode(etPhoneNumber.getEditValue(), etVerifyCode.getEditValue());
+ }
+ }
+ break;
+ case R.id.tv_other_login:
+ XToastUtils.info("其他登录方式");
+ break;
+ case R.id.tv_forget_password:
+ XToastUtils.info("忘记密码");
+ break;
+ case R.id.tv_user_protocol:
+ XToastUtils.info("用户协议");
+ break;
+ case R.id.tv_privacy_protocol:
+ XToastUtils.info("隐私政策");
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * 获取验证码
+ */
+ private void getVerifyCode(String phoneNumber) {
+ // TODO: 2019-11-18 这里只是界面演示而已
+ mCountDownHelper.start();
+ }
+
+ /**
+ * 根据验证码登录
+ *
+ * @param phoneNumber 手机号
+ * @param verifyCode 验证码
+ */
+ private void loginByVerifyCode(String phoneNumber, String verifyCode) {
+ // TODO: 2019-11-18 这里只是界面演示而已
+ String token = RandomUtils.getRandomNumbersAndLetters(16);
+ if (TokenUtils.handleLoginSuccess(token)) {
+ popToBack();
+ ActivityUtils.startActivity(MainActivity.class);
+ }
+ }
+
+
+ @Override
+ public void onDestroyView() {
+ if (mCountDownHelper != null) {
+ mCountDownHelper.recycle();
+ }
+ super.onDestroyView();
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/SettingFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/SettingFragment.java
index 9af0f967..ad5c81c5 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/SettingFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/SettingFragment.java
@@ -56,7 +56,7 @@ protected void initViews() {
stvSwitchCustomTheme.setSwitchIsChecked(SettingSPUtils.getInstance().isUseCustomTheme());
stvSwitchCustomTheme.setOnSuperTextViewClickListener(new SuperTextView.OnSuperTextViewClickListener() {
@Override
- public void onClickListener(SuperTextView superTextView) {
+ public void onClick(SuperTextView superTextView) {
stvSwitchCustomTheme.setSwitchIsChecked(!stvSwitchCustomTheme.getSwitchIsChecked(), false);
}
});
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/FlowLayoutFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/FlowLayoutFragment.java
index 52638935..5e596225 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/FlowLayoutFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/FlowLayoutFragment.java
@@ -3,6 +3,7 @@
import com.xuexiang.xpage.annotation.Page;
import com.xuexiang.xuidemo.R;
import com.xuexiang.xuidemo.base.ComponentContainerFragment;
+import com.xuexiang.xuidemo.fragment.components.flowlayout.FlexboxLayoutFragment;
import com.xuexiang.xuidemo.fragment.components.flowlayout.FlowTagLayoutFragment;
import com.xuexiang.xuidemo.fragment.components.flowlayout.NormalFlowLayoutFragment;
@@ -22,7 +23,8 @@ public class FlowLayoutFragment extends ComponentContainerFragment {
protected Class[] getPagesClasses() {
return new Class[]{
FlowTagLayoutFragment.class,
- NormalFlowLayoutFragment.class
+ NormalFlowLayoutFragment.class,
+ FlexboxLayoutFragment.class
};
}
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/ImageViewFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/ImageViewFragment.java
index 4658d9c9..e2edca8b 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/ImageViewFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/ImageViewFragment.java
@@ -4,8 +4,7 @@
import com.xuexiang.xuidemo.R;
import com.xuexiang.xuidemo.base.ComponentContainerFragment;
import com.xuexiang.xuidemo.fragment.components.imageview.ImageEditFragment;
-import com.xuexiang.xuidemo.fragment.components.imageview.edit.ImageCropFragment;
-import com.xuexiang.xuidemo.fragment.components.imageview.edit.ImageEnhanceFragment;
+import com.xuexiang.xuidemo.fragment.components.imageview.ImageLoadStrategyFragment;
import com.xuexiang.xuidemo.fragment.components.imageview.PreviewFragment;
import com.xuexiang.xuidemo.fragment.components.imageview.RadiusImageViewFragment;
import com.xuexiang.xuidemo.fragment.components.imageview.pictureselector.PictureSelectorFragment;
@@ -27,7 +26,8 @@ protected Class[] getPagesClasses() {
RadiusImageViewFragment.class,
PictureSelectorFragment.class,
PreviewFragment.class,
- ImageEditFragment.class
+ ImageEditFragment.class,
+ ImageLoadStrategyFragment.class
};
}
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/LayoutFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/LayoutFragment.java
index e1dab7a7..b6ba9bf9 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/LayoutFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/LayoutFragment.java
@@ -21,6 +21,7 @@
import com.xuexiang.xuidemo.R;
import com.xuexiang.xuidemo.base.ComponentContainerFragment;
import com.xuexiang.xuidemo.fragment.components.layout.AlphaViewFragment;
+import com.xuexiang.xuidemo.fragment.components.layout.ExpandableLayoutFragment;
import com.xuexiang.xuidemo.fragment.components.layout.XUILayoutFragment;
/**
@@ -38,7 +39,8 @@ public class LayoutFragment extends ComponentContainerFragment {
protected Class[] getPagesClasses() {
return new Class[]{
AlphaViewFragment.class,
- XUILayoutFragment.class
+ XUILayoutFragment.class,
+ ExpandableLayoutFragment.class
};
}
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/MarqueeViewFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/MarqueeViewFragment.java
index d25cf3ff..9bd14b98 100755
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/MarqueeViewFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/MarqueeViewFragment.java
@@ -1,5 +1,6 @@
package com.xuexiang.xuidemo.fragment.components;
+import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -59,7 +60,7 @@ protected void initViews() {
marqueeView1.startFlipping();
marqueeFactory1.setOnItemClickListener(new MarqueeFactory.OnItemClickListener() {
@Override
- public void onItemClickListener(MarqueeFactory.ViewHolder holder) {
+ public void onItemClick(View view, MarqueeFactory.ViewHolder holder) {
XToastUtils.toast(holder.getData());
}
});
@@ -68,7 +69,7 @@ public void onItemClickListener(MarqueeFactory.ViewHolder hold
MarqueeFactory marqueeFactory2 = new SimpleNoticeMF(getContext());
marqueeFactory2.setOnItemClickListener(new MarqueeFactory.OnItemClickListener() {
@Override
- public void onItemClickListener(MarqueeFactory.ViewHolder holder) {
+ public void onItemClick(View view, MarqueeFactory.ViewHolder holder) {
XToastUtils.toast(holder.getData());
}
});
@@ -81,7 +82,7 @@ public void onItemClickListener(MarqueeFactory.ViewHolder hold
MarqueeFactory marqueeFactory3 = new SimpleNoticeMF(getContext());
marqueeFactory3.setOnItemClickListener(new MarqueeFactory.OnItemClickListener() {
@Override
- public void onItemClickListener(MarqueeFactory.ViewHolder holder) {
+ public void onItemClick(View view, MarqueeFactory.ViewHolder holder) {
XToastUtils.toast(holder.getData());
}
});
@@ -95,7 +96,7 @@ public void onItemClickListener(MarqueeFactory.ViewHolder hold
MarqueeFactory marqueeFactory4 = new SimpleNoticeMF(getContext());
marqueeFactory4.setOnItemClickListener(new MarqueeFactory.OnItemClickListener() {
@Override
- public void onItemClickListener(MarqueeFactory.ViewHolder holder) {
+ public void onItemClick(View view, MarqueeFactory.ViewHolder holder) {
XToastUtils.toast(holder.getData());
}
});
@@ -111,7 +112,7 @@ public void onItemClickListener(MarqueeFactory.ViewHolder hold
MarqueeFactory marqueeFactory5 = new ComplexViewMF(getContext());
marqueeFactory5.setOnItemClickListener(new MarqueeFactory.OnItemClickListener() {
@Override
- public void onItemClickListener(MarqueeFactory.ViewHolder holder) {
+ public void onItemClick(View view, MarqueeFactory.ViewHolder holder) {
XToastUtils.toast(holder.getData().toString());
}
});
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/SpinnerFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/SpinnerFragment.java
index 111d1f56..ada1a273 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/SpinnerFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/SpinnerFragment.java
@@ -3,6 +3,7 @@
import com.xuexiang.xpage.annotation.Page;
import com.xuexiang.xuidemo.R;
import com.xuexiang.xuidemo.base.ComponentContainerFragment;
+import com.xuexiang.xuidemo.fragment.components.spinner.DropDownMenuFragment;
import com.xuexiang.xuidemo.fragment.components.spinner.SpinnerStyleFragment;
/**
@@ -23,6 +24,7 @@ public class SpinnerFragment extends ComponentContainerFragment {
protected Class[] getPagesClasses() {
return new Class[]{
SpinnerStyleFragment.class,
+ DropDownMenuFragment.class
};
}
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/banner/ViewPagerBannerFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/banner/ViewPagerBannerFragment.java
index b3fdfad4..43e0721b 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/banner/ViewPagerBannerFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/banner/ViewPagerBannerFragment.java
@@ -51,7 +51,7 @@
* @date 2017/10/15 下午1:17
*/
@Page(name = "使用ViewPager实现的Banner")
-public class ViewPagerBannerFragment extends BaseFragment {
+public class ViewPagerBannerFragment extends BaseFragment implements BaseBanner.OnItemClickListener {
private List mData;
@BindView(R.id.sib_simple_usage)
@@ -136,10 +136,9 @@ public void onClick(View v) {
*/
private void sib_simple_usage() {
sib_simple_usage.setSource(mData)
- .setOnItemClickL(new BaseBanner.OnItemClickL() {
+ .setOnItemClickListener(new BaseBanner.OnItemClickListener() {
@Override
- public void onItemClick(int position) {
- XToastUtils.toast("position--->" + position);
+ public void onItemClick(View view, BannerItem t, int position) {
}
})
.setIsOnePageLoop(false).startScroll();
@@ -171,12 +170,7 @@ private void sib_the_most_comlex_usage() {
// .setPeriod(10) //scroll setPeriod
.setSource(mData) //data source list
.setTransformerClass(ZoomOutSlideTransformer.class) //set page transformer
- .setOnItemClickL(new BaseBanner.OnItemClickL() {
- @Override
- public void onItemClick(int position) {
- XToastUtils.toast("position--->" + position);
- }
- })
+ .setOnItemClickListener(this)
.startScroll(); //start scroll,the last method to call
}
@@ -188,12 +182,7 @@ private void sib_res() {
// .setIndicatorStyle(SimpleImageBanner.STYLE_DRAWABLE_RESOURCE)
// .setIndicatorSelectorRes(R.mipmap.banner_dot_unselect, R.mipmap.banner_dot_select)
.setSource(mData)
- .setOnItemClickL(new BaseBanner.OnItemClickL() {
- @Override
- public void onItemClick(int position) {
- XToastUtils.toast("position--->" + position);
- }
- })
+ .setOnItemClickListener(this)
.startScroll();
}
@@ -204,12 +193,7 @@ private void sib_rectangle() {
sib_rectangle
// .setIndicatorCornerRadius(0)
.setSource(mData)
- .setOnItemClickL(new BaseBanner.OnItemClickL() {
- @Override
- public void onItemClick(int position) {
- XToastUtils.toast("position--->" + position);
- }
- })
+ .setOnItemClickListener(this)
.startScroll();
}
@@ -223,12 +207,7 @@ private void sib_corner_rectangle() {
// .setIndicatorHeight(4)
// .setIndicatorCornerRadius(2)
.setSource(mData)
- .setOnItemClickL(new BaseBanner.OnItemClickL() {
- @Override
- public void onItemClick(int position) {
- XToastUtils.toast("position--->" + position);
- }
- })
+ .setOnItemClickListener(this)
.startScroll();
}
@@ -240,12 +219,7 @@ public void onItemClick(int position) {
private void sib_indicator_right_with_text() {
sib_indicator_right_with_text
.setSource(mData)
- .setOnItemClickL(new BaseBanner.OnItemClickL() {
- @Override
- public void onItemClick(int position) {
- XToastUtils.toast("position--->" + position);
- }
- })
+ .setOnItemClickListener(this)
.startScroll();
}
@@ -255,12 +229,7 @@ public void onItemClick(int position) {
private void sib_indicator_left_with_text() {
sib_indicator_left_with_text
.setSource(mData)
- .setOnItemClickL(new BaseBanner.OnItemClickL() {
- @Override
- public void onItemClick(int position) {
- XToastUtils.toast("position--->" + position);
- }
- })
+ .setOnItemClickListener(this)
.startScroll();
}
@@ -271,12 +240,7 @@ private void sib_anim() {
sib_anim
.setSelectAnimClass(ZoomInEnter.class)
.setSource(mData)
- .setOnItemClickL(new BaseBanner.OnItemClickL() {
- @Override
- public void onItemClick(int position) {
- XToastUtils.toast("position--->" + position);
- }
- })
+ .setOnItemClickListener(this)
.startScroll();
}
@@ -289,12 +253,7 @@ private void sib_anim2() {
.setSelectAnimClass(RotateEnter.class)
.setUnselectAnimClass(NoAnimExist.class)
.setSource(mData)
- .setOnItemClickL(new BaseBanner.OnItemClickL() {
- @Override
- public void onItemClick(int position) {
- XToastUtils.toast("position--->" + position);
- }
- })
+ .setOnItemClickListener(this)
.startScroll();
}
@@ -309,9 +268,9 @@ private void stb() {
}
stb
.setSource(titles)
- .setOnItemClickL(new BaseBanner.OnItemClickL() {
+ .setOnItemClickListener(new BaseBanner.OnItemClickListener() {
@Override
- public void onItemClick(int position) {
+ public void onItemClick(View view, String item, int position) {
XToastUtils.toast("position--->" + position);
}
})
@@ -355,4 +314,9 @@ public void onDestroyView() {
stb.recycle();
super.onDestroyView();
}
+
+ @Override
+ public void onItemClick(View view, BannerItem item, int position) {
+ XToastUtils.toast("position--->" + position + ", item:" + item.title);
+ }
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/edittext/VerifyCodeEditTextFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/edittext/VerifyCodeEditTextFragment.java
index 4a303254..a0706d65 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/edittext/VerifyCodeEditTextFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/edittext/VerifyCodeEditTextFragment.java
@@ -22,6 +22,8 @@ public class VerifyCodeEditTextFragment extends BaseFragment implements VerifyCo
VerifyCodeEditText vcet2;
@BindView(R.id.vcet_3)
VerifyCodeEditText vcet3;
+ @BindView(R.id.vcet_4)
+ VerifyCodeEditText vcet4;
@Override
protected int getLayoutId() {
@@ -38,6 +40,7 @@ protected void initListeners() {
vcet1.setOnInputListener(this);
vcet2.setOnInputListener(this);
vcet3.setOnInputListener(this);
+ vcet4.setOnInputListener(this);
}
@Override
@@ -60,5 +63,6 @@ public void onViewClicked() {
vcet1.clearInputValue();
vcet2.clearInputValue();
vcet3.clearInputValue();
+ vcet4.clearInputValue();
}
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/flowlayout/FlexboxLayoutFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/flowlayout/FlexboxLayoutFragment.java
new file mode 100644
index 00000000..ee84fc7d
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/flowlayout/FlexboxLayoutFragment.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.components.flowlayout;
+
+import android.view.View;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.google.android.flexbox.FlexDirection;
+import com.google.android.flexbox.FlexWrap;
+import com.google.android.flexbox.FlexboxLayoutManager;
+import com.google.android.flexbox.JustifyContent;
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.adapter.recyclerview.RecyclerViewHolder;
+import com.xuexiang.xui.utils.ResUtils;
+import com.xuexiang.xui.widget.toast.XToast;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.adapter.FlexboxLayoutAdapter;
+import com.xuexiang.xuidemo.base.BaseFragment;
+import com.xuexiang.xuidemo.utils.XToastUtils;
+import com.xuexiang.xutil.common.StringUtils;
+
+import butterknife.BindView;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-23 01:23
+ */
+@Page(name = "FlexboxLayoutManager + RecyclerView\n流标签")
+public class FlexboxLayoutFragment extends BaseFragment {
+
+ @BindView(R.id.recycler_view_1)
+ RecyclerView recyclerView1;
+ @BindView(R.id.recycler_view_2)
+ RecyclerView recyclerView2;
+ @BindView(R.id.recycler_view_3)
+ RecyclerView recyclerView3;
+ @BindView(R.id.recycler_view_4)
+ RecyclerView recyclerView4;
+
+ private FlexboxLayoutAdapter mAdapter1;
+ private FlexboxLayoutAdapter mAdapter2;
+ private FlexboxLayoutAdapter mAdapter3;
+ private FlexboxLayoutAdapter mAdapter4;
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.fragment_flexbox_layout;
+ }
+
+ @Override
+ protected void initViews() {
+ String[] array = ResUtils.getStringArray(R.array.tags_values);
+
+ recyclerView1.setLayoutManager(getFlexboxLayoutManager());
+ recyclerView1.setAdapter(mAdapter1 = new FlexboxLayoutAdapter(array));
+
+ recyclerView2.setLayoutManager(getFlexboxLayoutManager());
+ recyclerView2.setAdapter(mAdapter2 = new FlexboxLayoutAdapter(array));
+
+ recyclerView3.setLayoutManager(getFlexboxLayoutManager());
+ recyclerView3.setAdapter(mAdapter3 = new FlexboxLayoutAdapter(array).setCancelable(true));
+
+ recyclerView4.setLayoutManager(getFlexboxLayoutManager());
+ recyclerView4.setItemAnimator(null);
+ recyclerView4.setAdapter(mAdapter4 = new FlexboxLayoutAdapter(array).setIsMultiSelectMode(true));
+
+ mAdapter2.select(2);
+ mAdapter3.select(3);
+ mAdapter4.multiSelect(1, 2, 3);
+ }
+
+
+ private FlexboxLayoutManager getFlexboxLayoutManager() {
+ //设置布局管理器
+ FlexboxLayoutManager flexboxLayoutManager = new FlexboxLayoutManager(getContext());
+ //flexDirection 属性决定主轴的方向(即项目的排列方向)。类似 LinearLayout 的 vertical 和 horizontal:
+ // 主轴为水平方向,起点在左端。
+ flexboxLayoutManager.setFlexDirection(FlexDirection.ROW);
+ //flexWrap 默认情况下 Flex 跟 LinearLayout 一样,都是不带换行排列的,但是flexWrap属性可以支持换行排列:
+ // 按正常方向换行
+ flexboxLayoutManager.setFlexWrap(FlexWrap.WRAP);
+ //justifyContent 属性定义了项目在主轴上的对齐方式:
+ // 交叉轴的起点对齐
+ flexboxLayoutManager.setJustifyContent(JustifyContent.FLEX_START);
+ return flexboxLayoutManager;
+ }
+
+
+ @Override
+ protected void initListeners() {
+ mAdapter1.setOnItemClickListener(new RecyclerViewHolder.OnItemClickListener() {
+ @Override
+ public void onItemClick(View itemView, String item, int position) {
+ XToastUtils.toast("点击了:" + item);
+ }
+ });
+
+ mAdapter2.setOnItemClickListener(new RecyclerViewHolder.OnItemClickListener() {
+ @Override
+ public void onItemClick(View itemView, String item, int position) {
+ if (mAdapter2.select(position)) {
+ XToastUtils.toast("选中的内容:" + mAdapter2.getSelectContent());
+ }
+ }
+ });
+
+ mAdapter3.setOnItemClickListener(new RecyclerViewHolder.OnItemClickListener() {
+ @Override
+ public void onItemClick(View itemView, String item, int position) {
+ if (mAdapter3.select(position)) {
+ XToastUtils.toast("选中的内容:" + mAdapter3.getSelectContent());
+ }
+ }
+ });
+
+ mAdapter4.setOnItemClickListener(new RecyclerViewHolder.OnItemClickListener() {
+ @Override
+ public void onItemClick(View itemView, String item, int position) {
+ mAdapter4.select(position);
+ XToastUtils.toast("选中的内容:" + StringUtils.listToString(mAdapter4.getMultiContent(), ","));
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/imageview/ImageLoadStrategyFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/imageview/ImageLoadStrategyFragment.java
new file mode 100644
index 00000000..6a4d1cf1
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/imageview/ImageLoadStrategyFragment.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.components.imageview;
+
+import androidx.appcompat.widget.AppCompatImageView;
+
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.utils.DensityUtils;
+import com.xuexiang.xui.utils.ResUtils;
+import com.xuexiang.xui.widget.imageview.ImageLoader;
+import com.xuexiang.xui.widget.imageview.strategy.DiskCacheStrategyEnum;
+import com.xuexiang.xui.widget.imageview.strategy.ILoadListener;
+import com.xuexiang.xui.widget.imageview.strategy.LoadOption;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.base.BaseFragment;
+
+import butterknife.BindView;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-09 16:20
+ */
+@Page(name = "图片加载策略")
+public class ImageLoadStrategyFragment extends BaseFragment {
+
+ private static final String PICTURE_URL = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1573298332486&di=57555a4ffbd9c2c09f12042f0f2b8ba6&imgtype=0&src=http%3A%2F%2Fimg.pconline.com.cn%2Fimages%2Fupload%2Fupc%2Ftx%2Fwallpaper%2F1212%2F10%2Fc1%2F16491245_1355126013759.jpg";
+ private static final String PICTURE_URL1 = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1573298947875&di=a2d6f04cd74ad2a7db74eb5d2395f2c6&imgtype=0&src=http%3A%2F%2Fupload.17u.net%2Fuploadpicbase%2Fimage%2F201306150338029631.jpg";
+ private static final String PICTURE_URL2 = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1573298976039&di=ba80603c68dc64a4efc55e19065eacf1&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fc%2F59bcd50cb8281.jpg";
+
+ @BindView(R.id.iv_content)
+ AppCompatImageView ivContent;
+ @BindView(R.id.iv_content1)
+ AppCompatImageView ivContent1;
+ @BindView(R.id.iv_content2)
+ AppCompatImageView ivContent2;
+
+ /**
+ * 布局的资源id
+ *
+ * @return
+ */
+ @Override
+ protected int getLayoutId() {
+ return R.layout.fragment_imageload_strategy;
+ }
+
+ /**
+ * 初始化控件
+ */
+ @Override
+ protected void initViews() {
+ getMessageLoader("加载中...");
+ ImageLoader.get().loadImage(ivContent, PICTURE_URL, DiskCacheStrategyEnum.NONE, new ILoadListener() {
+ @Override
+ public void onLoadSuccess() {
+ getMessageLoader().dismiss();
+ }
+ @Override
+ public void onLoadFailed(Throwable error) {
+ getMessageLoader().dismiss();
+ }
+ });
+ LoadOption option = LoadOption.of(DiskCacheStrategyEnum.ALL)
+ .setPlaceholder(ResUtils.getDrawable(R.drawable.xui_ic_default_img))
+ .setSize(DensityUtils.dp2px(200), DensityUtils.dp2px(100));
+ ImageLoader.get().loadImage(ivContent1, PICTURE_URL1, option);
+
+ ImageLoader.get().loadImage(ivContent2, PICTURE_URL2, ResUtils.getDrawable(R.drawable.xui_ic_default_img), DiskCacheStrategyEnum.AUTOMATIC);
+
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/imageview/edit/PhotoEditFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/imageview/edit/PhotoEditFragment.java
index 98a3127c..94b6e91d 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/imageview/edit/PhotoEditFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/imageview/edit/PhotoEditFragment.java
@@ -17,11 +17,14 @@
package com.xuexiang.xuidemo.fragment.components.imageview.edit;
+import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.view.View;
+import androidx.annotation.NonNull;
+
import com.xuexiang.xaop.annotation.Permission;
import com.xuexiang.xaop.annotation.SingleClick;
import com.xuexiang.xpage.annotation.Page;
@@ -35,6 +38,8 @@
import com.xuexiang.xui.widget.imageview.edit.ViewType;
import com.xuexiang.xuidemo.R;
import com.xuexiang.xuidemo.base.BaseFragment;
+import com.xuexiang.xuidemo.utils.Utils;
+import com.xuexiang.xuidemo.utils.XToastUtils;
import com.xuexiang.xutil.app.IntentUtils;
import com.xuexiang.xutil.app.PathUtils;
import com.xuexiang.xutil.display.ImageUtils;
@@ -50,7 +55,7 @@
* @author xuexiang
* @since 2019-10-28 10:56
*/
-@Page(name = "图片编辑\n画笔、橡皮檫、文字、滤镜")
+@Page(name = "图片编辑\n画笔、橡皮檫、文字、滤镜、保存")
public class PhotoEditFragment extends BaseFragment implements OnPhotoEditorListener {
@BindView(R.id.photo_editor_view)
@@ -81,7 +86,7 @@ protected void initViews() {
}
@SingleClick
- @OnClick({R.id.btn_select, R.id.btn_brush, R.id.btn_text, R.id.btn_rubber, R.id.iv_undo, R.id.iv_redo, R.id.btn_filter})
+ @OnClick({R.id.btn_select, R.id.btn_brush, R.id.btn_text, R.id.btn_rubber, R.id.iv_undo, R.id.iv_redo, R.id.btn_filter, R.id.btn_save})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.btn_select:
@@ -95,8 +100,8 @@ public void onViewClicked(View view) {
break;
case R.id.btn_brush:
mPhotoEditor.setBrushColor(ResUtils.getColor(R.color.xui_config_color_white))
- .setBrushSize(DensityUtils.dp2px(5))
- .setBrushDrawingMode(true);
+ .setBrushSize(DensityUtils.dp2px(5))
+ .setBrushDrawingMode(true);
break;
case R.id.btn_text:
final TextStyleBuilder styleBuilder = new TextStyleBuilder();
@@ -109,11 +114,37 @@ public void onViewClicked(View view) {
case R.id.btn_filter:
mPhotoEditor.setFilterEffect(PhotoFilter.GRAY_SCALE);
break;
+ case R.id.btn_save:
+ saveImage();
+ break;
default:
break;
}
}
+ /**
+ * 保存图片
+ */
+ @SuppressLint("MissingPermission")
+ @Permission(STORAGE)
+ private void saveImage() {
+ getMessageLoader("保存中...").show();
+ mPhotoEditor.saveAsFile(Utils.getImageSavePath(), new PhotoEditor.OnSaveListener() {
+ @Override
+ public void onSuccess(@NonNull String imagePath) {
+ getMessageLoader().dismiss();
+ if (photoEditorView != null) {
+ photoEditorView.getSource().setImageBitmap(ImageUtils.getBitmap(imagePath));
+ }
+ }
+ @Override
+ public void onFailure(@NonNull Exception exception) {
+ getMessageLoader().dismiss();
+ XToastUtils.error(exception);
+ }
+ });
+ }
+
@Permission(STORAGE)
private void selectImage() {
startActivityForResult(IntentUtils.getDocumentPickerIntent(IntentUtils.DocumentType.IMAGE), REQUEST_IMAGE);
@@ -128,6 +159,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
Uri uri = data.getData();
if (uri != null) {
mPhotoEditor.clearAllViews();
+ @SuppressLint("MissingPermission")
Bitmap bitmap = ImageUtils.getBitmap(PathUtils.getFilePathByUri(uri));
photoEditorView.getSource().setImageBitmap(bitmap);
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/ExpandableLayoutFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/ExpandableLayoutFragment.java
new file mode 100644
index 00000000..23f3e037
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/ExpandableLayoutFragment.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.components.layout;
+
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xuidemo.base.ComponentContainerFragment;
+import com.xuexiang.xuidemo.fragment.components.layout.expandable.ExpandableHorizontalFragment;
+import com.xuexiang.xuidemo.fragment.components.layout.expandable.ExpandableRecycleViewFragment;
+import com.xuexiang.xuidemo.fragment.components.layout.expandable.ExpandableSimpleFragment;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-22 14:18
+ */
+@Page(name = "可伸缩布局\n可水平、垂直伸缩")
+public class ExpandableLayoutFragment extends ComponentContainerFragment {
+ /**
+ * 获取页面的类集合[使用@Page注解进行注册的页面]
+ *
+ * @return
+ */
+ @Override
+ protected Class[] getPagesClasses() {
+ return new Class[]{
+ ExpandableSimpleFragment.class,
+ ExpandableHorizontalFragment.class,
+ ExpandableRecycleViewFragment.class
+ };
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/expandable/ExpandableHorizontalFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/expandable/ExpandableHorizontalFragment.java
new file mode 100644
index 00000000..10f1c5e1
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/expandable/ExpandableHorizontalFragment.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.components.layout.expandable;
+
+import androidx.appcompat.widget.AppCompatImageView;
+
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.widget.layout.ExpandableLayout;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.base.BaseFragment;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-22 14:42
+ */
+@Page(name = "水平伸缩使用")
+public class ExpandableHorizontalFragment extends BaseFragment {
+ @BindView(R.id.expandable_layout)
+ ExpandableLayout expandableLayout;
+ @BindView(R.id.expand_button)
+ AppCompatImageView expandButton;
+
+ /**
+ * 布局的资源id
+ *
+ * @return
+ */
+ @Override
+ protected int getLayoutId() {
+ return R.layout.fragment_expandable_horizontal;
+ }
+
+ /**
+ * 初始化控件
+ */
+ @Override
+ protected void initViews() {
+ expandableLayout.setOnExpansionChangedListener(new ExpandableLayout.OnExpansionChangedListener() {
+ @Override
+ public void onExpansionChanged(float expansion, int state) {
+ if (expandButton != null) {
+ expandButton.setRotation(expansion * 180);
+ }
+ }
+ });
+ }
+
+ @OnClick(R.id.expand_button)
+ public void onViewClicked() {
+ expandableLayout.toggle();
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/expandable/ExpandableRecycleViewFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/expandable/ExpandableRecycleViewFragment.java
new file mode 100644
index 00000000..9198ee48
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/expandable/ExpandableRecycleViewFragment.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.components.layout.expandable;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.utils.WidgetUtils;
+import com.xuexiang.xuidemo.DemoDataProvider;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.adapter.ExpandableListAdapter;
+import com.xuexiang.xuidemo.base.BaseFragment;
+
+import butterknife.BindView;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-22 15:33
+ */
+@Page(name = "在RecycleView中使用")
+public class ExpandableRecycleViewFragment extends BaseFragment {
+ @BindView(R.id.recycler_view)
+ RecyclerView recyclerView;
+
+ /**
+ * 布局的资源id
+ *
+ * @return
+ */
+ @Override
+ protected int getLayoutId() {
+ return R.layout.layout_common_recycleview;
+ }
+
+ /**
+ * 初始化控件
+ */
+ @Override
+ protected void initViews() {
+ WidgetUtils.initRecyclerView(recyclerView);
+
+ recyclerView.setAdapter(new ExpandableListAdapter(recyclerView, DemoDataProvider.getDemoData1()));
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/expandable/ExpandableSimpleFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/expandable/ExpandableSimpleFragment.java
new file mode 100644
index 00000000..01ff9869
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/layout/expandable/ExpandableSimpleFragment.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.components.layout.expandable;
+
+import android.util.Log;
+
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.widget.layout.ExpandableLayout;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.base.BaseFragment;
+import com.xuexiang.xuidemo.utils.XToastUtils;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+import static com.xuexiang.xui.widget.layout.ExpandableLayout.State.COLLAPSED;
+import static com.xuexiang.xui.widget.layout.ExpandableLayout.State.EXPANDED;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-22 14:21
+ */
+@Page(name = "可伸缩布局简单使用")
+public class ExpandableSimpleFragment extends BaseFragment {
+
+ @BindView(R.id.expandable_layout_1)
+ ExpandableLayout expandableLayout1;
+ @BindView(R.id.expandable_layout_2)
+ ExpandableLayout expandableLayout2;
+
+ /**
+ * 布局的资源id
+ *
+ * @return
+ */
+ @Override
+ protected int getLayoutId() {
+ return R.layout.fragment_expandable_simple;
+ }
+
+ /**
+ * 初始化控件
+ */
+ @Override
+ protected void initViews() {
+ expandableLayout1.setOnExpansionChangedListener(new ExpandableLayout.OnExpansionChangedListener() {
+ @Override
+ public void onExpansionChanged(float expansion, int state) {
+ Log.d("expandableLayout1", "State: " + state);
+ }
+ });
+
+ expandableLayout2.setOnExpansionChangedListener(new ExpandableLayout.OnExpansionChangedListener() {
+ @Override
+ public void onExpansionChanged(float expansion, int state) {
+ if (state == COLLAPSED) {
+ XToastUtils.toast("已收起");
+ } else if (state == EXPANDED) {
+ XToastUtils.toast("已展开");
+ }
+ }
+ });
+ }
+
+ @OnClick(R.id.expand_button)
+ public void onViewClicked() {
+ if (expandableLayout1.isExpanded()) {
+ expandableLayout1.collapse();
+ } else if (expandableLayout2.isExpanded()) {
+ expandableLayout2.collapse();
+ } else {
+ expandableLayout1.expand();
+ expandableLayout2.expand();
+ }
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/popupwindow/PopupWindowStyleFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/popupwindow/PopupWindowStyleFragment.java
index 3525f61a..297f7ec8 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/popupwindow/PopupWindowStyleFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/popupwindow/PopupWindowStyleFragment.java
@@ -5,8 +5,11 @@
import com.xuexiang.xaop.annotation.SingleClick;
import com.xuexiang.xpage.annotation.Page;
import com.xuexiang.xui.adapter.simple.AdapterItem;
+import com.xuexiang.xui.adapter.simple.ExpandableItem;
import com.xuexiang.xui.adapter.simple.XUISimpleAdapter;
+import com.xuexiang.xui.adapter.simple.XUISimpleExpandableListAdapter;
import com.xuexiang.xui.widget.actionbar.TitleBar;
+import com.xuexiang.xui.widget.popupwindow.popup.XUISimpleExpandablePopup;
import com.xuexiang.xui.widget.popupwindow.popup.XUISimplePopup;
import com.xuexiang.xuidemo.DemoDataProvider;
import com.xuexiang.xuidemo.R;
@@ -23,6 +26,7 @@
@Page(name = "弹出框统一样式")
public class PopupWindowStyleFragment extends BaseFragment {
private XUISimplePopup mListPopup;
+ private XUISimpleExpandablePopup mExpandableListPopup;
private XUISimplePopup mMenuPopup;
@Override
@@ -53,6 +57,7 @@ protected int getLayoutId() {
@Override
protected void initViews() {
initListPopup();
+ initExpandableListPopup();
initMenuPopup();
}
@@ -72,6 +77,17 @@ public void onItemClick(XUISimpleAdapter adapter, AdapterItem item, int position
.setHasDivider(true);
}
+ private void initExpandableListPopup() {
+ mExpandableListPopup = new XUISimpleExpandablePopup(getContext(), DemoDataProvider.expandableItems)
+ .create(DensityUtils.dip2px(getContext(), 200), DensityUtils.dip2px(getContext(), 200))
+ .setOnExpandableItemClickListener(false, new XUISimpleExpandablePopup.OnExpandableItemClickListener() {
+ @Override
+ public void onExpandableItemClick(XUISimpleExpandableListAdapter adapter, ExpandableItem group, int groupPosition, int childPosition) {
+ XToastUtils.toast(group.getChildItem(childPosition).getTitle());
+ }
+ });
+ }
+
private void initMenuPopup() {
mMenuPopup = new XUISimplePopup(getContext(), DemoDataProvider.menuItems)
.create(new XUISimplePopup.OnPopupItemClickListener() {
@@ -83,12 +99,16 @@ public void onItemClick(XUISimpleAdapter adapter, AdapterItem item, int position
}
@SingleClick
- @OnClick({R.id.btn_commonlist_popup, R.id.btn_menu_popup})
+ @OnClick({R.id.btn_commonlist_popup, R.id.btn_expandable_popup, R.id.btn_menu_popup})
void onClick(View v) {
switch (v.getId()) {
case R.id.btn_commonlist_popup:
mListPopup.showDown(v);
break;
+ case R.id.btn_expandable_popup:
+ mExpandableListPopup.clearExpandStatus();
+ mExpandableListPopup.showDown(v);
+ break;
case R.id.btn_menu_popup:
mMenuPopup.showDown(v);
break;
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/refresh/swipe/SwipeHeadFootViewFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/refresh/swipe/SwipeHeadFootViewFragment.java
index 63a89149..7ce4023d 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/refresh/swipe/SwipeHeadFootViewFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/refresh/swipe/SwipeHeadFootViewFragment.java
@@ -5,6 +5,7 @@
import com.scwang.smartrefresh.layout.adapter.SmartViewHolder;
import com.xuexiang.xpage.annotation.Page;
import com.xuexiang.xui.utils.WidgetUtils;
+import com.xuexiang.xui.widget.banner.widget.banner.BannerItem;
import com.xuexiang.xui.widget.banner.widget.banner.SimpleImageBanner;
import com.xuexiang.xui.widget.banner.widget.banner.base.BaseBanner;
import com.xuexiang.xuidemo.DemoDataProvider;
@@ -49,9 +50,9 @@ protected void initViews() {
banner = headerView.findViewById(R.id.sib_simple_usage);
banner.setSource(DemoDataProvider.getBannerList())
- .setOnItemClickL(new BaseBanner.OnItemClickL() {
+ .setOnItemClickListener(new BaseBanner.OnItemClickListener() {
@Override
- public void onItemClick(int position) {
+ public void onItemClick(View view, BannerItem item, int position) {
XToastUtils.toast("headBanner position--->" + position);
}
}).startScroll();
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/refresh/swipe/SwipeRefreshFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/refresh/swipe/SwipeRefreshFragment.java
index e3aa7a5b..919af9cd 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/refresh/swipe/SwipeRefreshFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/refresh/swipe/SwipeRefreshFragment.java
@@ -1,15 +1,20 @@
package com.xuexiang.xuidemo.fragment.components.refresh.swipe;
import android.os.Handler;
+import android.view.View;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.xuexiang.xpage.annotation.Page;
import com.xuexiang.xui.utils.WidgetUtils;
+import com.xuexiang.xui.widget.banner.widget.banner.BannerItem;
+import com.xuexiang.xui.widget.banner.widget.banner.SimpleImageBanner;
+import com.xuexiang.xui.widget.banner.widget.banner.base.BaseBanner;
import com.xuexiang.xuidemo.DemoDataProvider;
import com.xuexiang.xuidemo.R;
import com.xuexiang.xuidemo.adapter.SimpleRecyclerAdapter;
import com.xuexiang.xuidemo.base.BaseFragment;
+import com.xuexiang.xuidemo.utils.XToastUtils;
import com.xuexiang.xuidemo.widget.MaterialLoadMoreView;
import com.yanzhenjie.recyclerview.SwipeRecyclerView;
@@ -23,6 +28,7 @@
public class SwipeRefreshFragment extends BaseFragment {
private SimpleRecyclerAdapter mAdapter;
+ private SimpleImageBanner banner;
@BindView(R.id.recycler_view)
SwipeRecyclerView recyclerView;
@@ -32,6 +38,9 @@ public class SwipeRefreshFragment extends BaseFragment {
private Handler mHandler = new Handler();
private boolean mEnableLoadMore;
+
+ private int mIndex = 0;
+ MaterialLoadMoreView mLoadMoreView;
/**
* 布局的资源id
*
@@ -49,6 +58,19 @@ protected int getLayoutId() {
protected void initViews() {
WidgetUtils.initRecyclerView(recyclerView);
+ // HeaderView,必须在setAdapter之前调用
+ View headerView = getLayoutInflater().inflate(R.layout.include_head_view_banner, recyclerView, false);
+
+ banner = headerView.findViewById(R.id.sib_simple_usage);
+ banner.setSource(DemoDataProvider.getBannerList())
+ .setOnItemClickListener(new BaseBanner.OnItemClickListener() {
+ @Override
+ public void onItemClick(View view, BannerItem item, int position) {
+ XToastUtils.toast("headBanner position--->" + position);
+ }
+ }).startScroll();
+ recyclerView.addHeaderView(headerView);
+
recyclerView.setAdapter(mAdapter = new SimpleRecyclerAdapter());
swipeRefreshLayout.setColorSchemeColors(0xff0099cc, 0xffff4444, 0xff669900, 0xffaa66cc, 0xffff8800);
@@ -60,7 +82,7 @@ protected void initListeners() {
// 刷新监听。
swipeRefreshLayout.setOnRefreshListener(mRefreshListener);
- refresh();
+ autoRefresh();
}
/**
@@ -69,16 +91,17 @@ protected void initListeners() {
private SwipeRefreshLayout.OnRefreshListener mRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
- loadData();
+ refreshData();
}
};
- private void refresh() {
+ private void autoRefresh() {
swipeRefreshLayout.setRefreshing(true);
- loadData();
+ refreshData();
}
- private void loadData() {
+ private void refreshData() {
+ mIndex = 0;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
@@ -97,8 +120,6 @@ public void run() {
private void enableLoadMore() {
if (recyclerView != null && !mEnableLoadMore) {
mEnableLoadMore = true;
- //SwipeRefreshLayout不支持加载更多
-// recyclerView.useDefaultLoadMore();
useMaterialLoadMore();
// 加载更多的监听。
recyclerView.setLoadMoreListener(mLoadMoreListener);
@@ -107,9 +128,32 @@ private void enableLoadMore() {
}
private void useMaterialLoadMore() {
- MaterialLoadMoreView loadMoreView = new MaterialLoadMoreView(getContext());
- recyclerView.addFooterView(loadMoreView);
- recyclerView.setLoadMoreView(loadMoreView);
+ if (mLoadMoreView == null) {
+ mLoadMoreView = new MaterialLoadMoreView(getContext());
+ }
+ recyclerView.addFooterView(mLoadMoreView);
+ recyclerView.setLoadMoreView(mLoadMoreView);
+ }
+
+ /**
+ * 确保有数据加载了才开启加载更多
+ */
+ private void disEnableLoadMore() {
+ if (recyclerView != null && mEnableLoadMore) {
+ mEnableLoadMore = false;
+ disableMaterialLoadMore();
+ // 加载更多的监听。
+ recyclerView.setLoadMoreListener(null);
+ recyclerView.loadMoreFinish(false, false);
+ }
+ }
+
+ private void disableMaterialLoadMore() {
+ if (mLoadMoreView == null) {
+ mLoadMoreView = new MaterialLoadMoreView(getContext());
+ }
+ recyclerView.removeFooterView(mLoadMoreView);
+ recyclerView.setLoadMoreView(null);
}
/**
@@ -118,6 +162,7 @@ private void useMaterialLoadMore() {
private SwipeRecyclerView.LoadMoreListener mLoadMoreListener = new SwipeRecyclerView.LoadMoreListener() {
@Override
public void onLoadMore() {
+ mIndex ++;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
@@ -128,6 +173,9 @@ public void run() {
if (recyclerView != null) {
recyclerView.loadMoreFinish(false, true);
}
+ if (mIndex >= 2) {
+ disEnableLoadMore();
+ }
// 如果加载失败调用下面的方法,传入errorCode和errorMessage。
// errorCode随便传,你自定义LoadMoreView时可以根据errorCode判断错误类型。
// errorMessage是会显示到loadMoreView上的,用户可以看到。
@@ -140,9 +188,11 @@ public void run() {
@Override
public void onDestroyView() {
+ banner.recycle();
mHandler.removeCallbacksAndMessages(null);
super.onDestroyView();
}
+
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/spinner/DropDownMenuFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/spinner/DropDownMenuFragment.java
new file mode 100644
index 00000000..d9ce8244
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/spinner/DropDownMenuFragment.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.components.spinner;
+
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.GridView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.xuexiang.xaop.annotation.SingleClick;
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.utils.ResUtils;
+import com.xuexiang.xui.widget.actionbar.TitleBar;
+import com.xuexiang.xui.widget.spinner.DropDownMenu;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.adapter.dropdownmenu.CityDropDownAdapter;
+import com.xuexiang.xuidemo.adapter.dropdownmenu.ConstellationAdapter;
+import com.xuexiang.xuidemo.adapter.dropdownmenu.ListDropDownAdapter;
+import com.xuexiang.xuidemo.base.BaseFragment;
+import com.xuexiang.xutil.common.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import butterknife.BindView;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-28 15:24
+ */
+@Page(name = "DropDownMenu\n下拉选择菜单")
+public class DropDownMenuFragment extends BaseFragment {
+
+ @BindView(R.id.ddm_content)
+ DropDownMenu mDropDownMenu;
+
+ private String[] mHeaders = {"城市", "年龄", "性别", "星座"};
+ private List mPopupViews = new ArrayList<>();
+
+ private CityDropDownAdapter mCityAdapter;
+ private ListDropDownAdapter mAgeAdapter;
+ private ListDropDownAdapter mSexAdapter;
+ private ConstellationAdapter mConstellationAdapter;
+
+ private String[] mCitys;
+ private String[] mAges;
+ private String[] mSexs;
+ private String[] mConstellations;
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.fragment_drop_down_menu;
+ }
+
+ @Override
+ protected TitleBar initTitle() {
+ return super.initTitle().setLeftClickListener(new View.OnClickListener() {
+ @SingleClick
+ @Override
+ public void onClick(View v) {
+ handleBackPressed();
+ }
+ });
+ }
+
+ @Override
+ protected void initArgs() {
+ mCitys = ResUtils.getStringArray(R.array.city_entry);
+ mAges = ResUtils.getStringArray(R.array.age_entry);
+ mSexs = ResUtils.getStringArray(R.array.sex_entry);
+ mConstellations = ResUtils.getStringArray(R.array.constellation_entry);
+ }
+
+ @Override
+ protected void initViews() {
+ final ListView cityView = new ListView(getContext());
+ mCityAdapter = new CityDropDownAdapter(getContext(), mCitys);
+ cityView.setDividerHeight(0);
+ cityView.setAdapter(mCityAdapter);
+
+ //init age menu
+ final ListView ageView = new ListView(getContext());
+ ageView.setDividerHeight(0);
+ mAgeAdapter = new ListDropDownAdapter(getContext(), mAges);
+ ageView.setAdapter(mAgeAdapter);
+
+ //init sex menu
+ final ListView sexView = new ListView(getContext());
+ sexView.setDividerHeight(0);
+ mSexAdapter = new ListDropDownAdapter(getContext(), mSexs);
+ sexView.setAdapter(mSexAdapter);
+
+ //init constellation
+ final View constellationView = getLayoutInflater().inflate(R.layout.layout_drop_down_custom, null);
+ GridView constellation = constellationView.findViewById(R.id.constellation);
+ mConstellationAdapter = new ConstellationAdapter(getContext(), mConstellations);
+ constellation.setAdapter(mConstellationAdapter);
+ constellationView.findViewById(R.id.btn_ok).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mDropDownMenu.setTabMenuText(mConstellationAdapter.getSelectPosition() == 0 ? mHeaders[3] : mConstellationAdapter.getSelectItem());
+ mDropDownMenu.closeMenu();
+ }
+ });
+
+ //init mPopupViews
+ mPopupViews.add(cityView);
+ mPopupViews.add(ageView);
+ mPopupViews.add(sexView);
+ mPopupViews.add(constellationView);
+
+ //add item click event
+ cityView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ mCityAdapter.setSelectPosition(position);
+ mDropDownMenu.setTabMenuText(position == 0 ? mHeaders[0] : mCitys[position]);
+ mDropDownMenu.closeMenu();
+ }
+ });
+
+ ageView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ mAgeAdapter.setSelectPosition(position);
+ mDropDownMenu.setTabMenuText(position == 0 ? mHeaders[1] : mAges[position]);
+ mDropDownMenu.closeMenu();
+ }
+ });
+
+ sexView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ mSexAdapter.setSelectPosition(position);
+ mDropDownMenu.setTabMenuText(position == 0 ? mHeaders[2] : mSexs[position]);
+ mDropDownMenu.closeMenu();
+ }
+ });
+
+ constellation.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ mConstellationAdapter.setSelectPosition(position);
+ }
+ });
+
+ //init context view
+ TextView contentView = new TextView(getContext());
+ contentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ contentView.setText("内容显示区域");
+ contentView.setGravity(Gravity.CENTER);
+ contentView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
+
+ //init dropdownview
+ mDropDownMenu.setDropDownMenu(mHeaders, mPopupViews, contentView);
+ }
+
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ handleBackPressed();
+ }
+ return true;
+ }
+
+ private void handleBackPressed() {
+ if (mDropDownMenu.isShowing()) {
+ mDropDownMenu.closeMenu();
+ } else {
+ popToBack();
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/tabbar/TabControlViewFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/tabbar/TabControlViewFragment.java
index 62970f01..46f93536 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/tabbar/TabControlViewFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/tabbar/TabControlViewFragment.java
@@ -75,7 +75,7 @@ private void initMultiTabControlView() {
mMultiTabControlView.setOnMultiTabSelectionChangedListener(new MultiTabControlView.OnMultiTabSelectionChangedListener() {
@Override
public void newSelection(String title, String value, boolean isChecked) {
- XToastUtils.toast("选中了:" + title + ", 选中的值为:" + value + ", isChecked:" + isChecked);
+ XToastUtils.toast((isChecked ? "选中了:" : "取消了:") + title + ", 值为:" + value);
}
});
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/textview/supertextview/SuperClickFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/textview/supertextview/SuperClickFragment.java
index e60b9d60..ce19d166 100755
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/textview/supertextview/SuperClickFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/textview/supertextview/SuperClickFragment.java
@@ -4,8 +4,10 @@
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageView;
+import android.widget.TextView;
import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.widget.layout.ExpandableLayout;
import com.xuexiang.xui.widget.textview.badge.Badge;
import com.xuexiang.xui.widget.textview.badge.BadgeView;
import com.xuexiang.xui.widget.textview.supertextview.SuperTextView;
@@ -25,12 +27,16 @@ public class SuperClickFragment extends BaseFragment {
SuperTextView superTextView_switch;
@BindView(R.id.super_message_tv)
SuperTextView stvMessage;
+ @BindView(R.id.stv_expandable)
+ SuperTextView stvExpandable;
+ @BindView(R.id.expandable_layout)
+ ExpandableLayout mExpandableLayout;
@BindView(R.id.stv_name)
SuperTextView stvName;
@BindView(R.id.stv_phone)
SuperTextView stvPhone;
- Badge mBadge;
+ private Badge mBadge;
@Override
protected int getLayoutId() {
@@ -56,68 +62,68 @@ protected void initListeners() {
*/
superTextView.setOnSuperTextViewClickListener(new SuperTextView.OnSuperTextViewClickListener() {
@Override
- public void onClickListener(SuperTextView superTextView) {
+ public void onClick(SuperTextView superTextView) {
XToastUtils.toast("整个item的点击事件");
}
}).setLeftTopTvClickListener(new SuperTextView.OnLeftTopTvClickListener() {
@Override
- public void onClickListener() {
+ public void onClick(TextView textView) {
XToastUtils.toast(superTextView.getLeftTopString());
}
}).setLeftTvClickListener(new SuperTextView.OnLeftTvClickListener() {
@Override
- public void onClickListener() {
+ public void onClick(TextView textView) {
XToastUtils.toast(superTextView.getLeftString());
}
}).setLeftBottomTvClickListener(new SuperTextView.OnLeftBottomTvClickListener() {
@Override
- public void onClickListener() {
+ public void onClick(TextView textView) {
XToastUtils.toast(superTextView.getLeftBottomString());
}
}).setCenterTopTvClickListener(new SuperTextView.OnCenterTopTvClickListener() {
@Override
- public void onClickListener() {
+ public void onClick(TextView textView) {
XToastUtils.toast(superTextView.getCenterTopString());
}
}).setCenterTvClickListener(new SuperTextView.OnCenterTvClickListener() {
@Override
- public void onClickListener() {
+ public void onClick(TextView textView) {
XToastUtils.toast(superTextView.getCenterString());
}
}).setCenterBottomTvClickListener(new SuperTextView.OnCenterBottomTvClickListener() {
@Override
- public void onClickListener() {
+ public void onClick(TextView textView) {
XToastUtils.toast(superTextView.getCenterBottomString());
}
}).setRightTopTvClickListener(new SuperTextView.OnRightTopTvClickListener() {
@Override
- public void onClickListener() {
+ public void onClick(TextView textView) {
XToastUtils.toast(superTextView.getRightTopString());
}
}).setRightTvClickListener(new SuperTextView.OnRightTvClickListener() {
@Override
- public void onClickListener() {
+ public void onClick(TextView textView) {
XToastUtils.toast(superTextView.getRightString());
}
}).setRightBottomTvClickListener(new SuperTextView.OnRightBottomTvClickListener() {
@Override
- public void onClickListener() {
+ public void onClick(TextView textView) {
XToastUtils.toast(superTextView.getRightBottomString());
}
}).setLeftImageViewClickListener(new SuperTextView.OnLeftImageViewClickListener() {
@Override
- public void onClickListener(ImageView imageView) {
+ public void onClick(ImageView imageView) {
}
}).setRightImageViewClickListener(new SuperTextView.OnRightImageViewClickListener() {
@Override
- public void onClickListener(ImageView imageView) {
+ public void onClick(ImageView imageView) {
}
});
superTextView_cb.setOnSuperTextViewClickListener(new SuperTextView.OnSuperTextViewClickListener() {
@Override
- public void onClickListener(SuperTextView superTextView) {
+ public void onClick(SuperTextView superTextView) {
superTextView.setCheckBoxChecked(!superTextView.getCheckBoxIsChecked());
}
}).setCheckBoxCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@@ -129,7 +135,7 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
superTextView_switch.setOnSuperTextViewClickListener(new SuperTextView.OnSuperTextViewClickListener() {
@Override
- public void onClickListener(SuperTextView superTextView) {
+ public void onClick(SuperTextView superTextView) {
superTextView.setSwitchIsChecked(!superTextView.getSwitchIsChecked(), false);
}
}).setSwitchCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@@ -141,7 +147,7 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
stvMessage.setOnSuperTextViewClickListener(new SuperTextView.OnSuperTextViewClickListener() {
@Override
- public void onClickListener(SuperTextView superTextView) {
+ public void onClick(SuperTextView superTextView) {
mBadge.hide(true);
}
});
@@ -159,6 +165,26 @@ public void onClick(View v) {
XToastUtils.toast("点击监听");
}
});
+
+
+ mExpandableLayout.setOnExpansionChangedListener(new ExpandableLayout.OnExpansionChangedListener() {
+ @Override
+ public void onExpansionChanged(float expansion, int state) {
+ if (stvExpandable != null && stvExpandable.getRightIconIV() != null) {
+ stvExpandable.getRightIconIV().setRotation(expansion * 90);
+ }
+ }
+ });
+ stvExpandable.setOnSuperTextViewClickListener(new SuperTextView.OnSuperTextViewClickListener() {
+ @Override
+ public void onClick(SuperTextView superTextView) {
+ if (mExpandableLayout != null) {
+ mExpandableLayout.toggle();
+ }
+ }
+ });
+
+
}
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/IconFontFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/IconFontFragment.java
index ef137584..c584f0fb 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/IconFontFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/IconFontFragment.java
@@ -17,12 +17,16 @@
package com.xuexiang.xuidemo.fragment.expands;
+import android.view.View;
+
import com.xuexiang.xpage.annotation.Page;
import com.xuexiang.xpage.core.PageOption;
+import com.xuexiang.xui.widget.actionbar.TitleBar;
import com.xuexiang.xuidemo.R;
import com.xuexiang.xuidemo.base.BaseSimpleListFragment;
import com.xuexiang.xuidemo.fragment.expands.iconfont.SimpleIconFontFragment;
import com.xuexiang.xuidemo.fragment.expands.iconfont.XUIIconFontDisplayFragment;
+import com.xuexiang.xuidemo.utils.Utils;
import com.xuexiang.xuidemo.widget.iconfont.IconFontActivity;
import java.util.List;
@@ -56,4 +60,22 @@ protected void onItemClick(int position) {
break;
}
}
+
+ @Override
+ protected TitleBar initTitle() {
+ TitleBar titleBar = super.initTitle();
+ titleBar.addAction(new TitleBar.TextAction("图标库") {
+ @Override
+ public void performAction(View view) {
+ Utils.goWeb(getContext(), "https://www.iconfont.cn/");
+ }
+ });
+ titleBar.addAction(new TitleBar.TextAction("Github") {
+ @Override
+ public void performAction(View view) {
+ Utils.goWeb(getContext(), "https://github.com/mikepenz/Android-Iconics");
+ }
+ });
+ return titleBar;
+ }
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/LinkageRecyclerViewFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/LinkageRecyclerViewFragment.java
new file mode 100644
index 00000000..e0358522
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/LinkageRecyclerViewFragment.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.expands;
+
+import android.view.View;
+
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.widget.actionbar.TitleBar;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.base.ComponentContainerFragment;
+import com.xuexiang.xuidemo.fragment.expands.linkage.LinkageRecyclerViewCustomFragment;
+import com.xuexiang.xuidemo.fragment.expands.linkage.LinkageRecyclerViewElemeFragment;
+import com.xuexiang.xuidemo.fragment.expands.linkage.LinkageRecyclerViewSimpleFragment;
+import com.xuexiang.xuidemo.utils.Utils;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-25 11:24
+ */
+@Page(name = "双列表联动", extra = R.drawable.ic_expand_linkage_list)
+public class LinkageRecyclerViewFragment extends ComponentContainerFragment {
+ /**
+ * 获取页面的类集合[使用@Page注解进行注册的页面]
+ *
+ * @return
+ */
+ @Override
+ protected Class[] getPagesClasses() {
+ return new Class[]{
+ LinkageRecyclerViewSimpleFragment.class,
+ LinkageRecyclerViewCustomFragment.class,
+ LinkageRecyclerViewElemeFragment.class
+ };
+ }
+
+ @Override
+ protected TitleBar initTitle() {
+ TitleBar titleBar = super.initTitle();
+ titleBar.addAction(new TitleBar.TextAction("Github") {
+ @Override
+ public void performAction(View view) {
+ Utils.goWeb(getContext(), "https://github.com/KunMinX/Linkage-RecyclerView");
+ }
+ });
+ return titleBar;
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/LinkageRecyclerViewCustomFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/LinkageRecyclerViewCustomFragment.java
new file mode 100644
index 00000000..2e510643
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/LinkageRecyclerViewCustomFragment.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.expands.linkage;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.kunminx.linkage.LinkageRecyclerView;
+import com.kunminx.linkage.adapter.viewholder.LinkagePrimaryViewHolder;
+import com.kunminx.linkage.adapter.viewholder.LinkageSecondaryViewHolder;
+import com.kunminx.linkage.bean.BaseGroupedItem;
+import com.xuexiang.xaop.annotation.SingleClick;
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.utils.SnackbarUtils;
+import com.xuexiang.xui.widget.actionbar.TitleBar;
+import com.xuexiang.xuidemo.DemoDataProvider;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.base.BaseFragment;
+import com.xuexiang.xuidemo.fragment.expands.linkage.custom.CustomGroupedItem;
+import com.xuexiang.xuidemo.fragment.expands.linkage.custom.CustomLinkagePrimaryAdapterConfig;
+import com.xuexiang.xuidemo.fragment.expands.linkage.custom.CustomLinkageSecondaryAdapterConfig;
+
+import butterknife.BindView;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-25 16:52
+ */
+@Page(name = "双列表自定义样式")
+public class LinkageRecyclerViewCustomFragment extends BaseFragment implements CustomLinkagePrimaryAdapterConfig.OnPrimaryItemClickListener, CustomLinkageSecondaryAdapterConfig.OnSecondaryItemClickListener {
+
+ @BindView(R.id.linkage)
+ LinkageRecyclerView linkage;
+
+ /**
+ * 布局的资源id
+ *
+ * @return
+ */
+ @Override
+ protected int getLayoutId() {
+ return R.layout.fragment_linkage_recyclerview;
+ }
+
+ @Override
+ protected TitleBar initTitle() {
+ TitleBar titleBar = super.initTitle();
+ titleBar.addAction(new TitleBar.TextAction("切换") {
+ @SingleClick
+ @Override
+ public void performAction(View view) {
+ if (linkage != null) {
+ linkage.setGridMode(!linkage.isGridMode());
+ }
+ }
+ });
+ return titleBar;
+ }
+
+ /**
+ * 初始化控件
+ */
+ @Override
+ protected void initViews() {
+ linkage.init(DemoDataProvider.getCustomGroupItems(), new CustomLinkagePrimaryAdapterConfig(this), new CustomLinkageSecondaryAdapterConfig(this));
+
+ }
+
+ @Override
+ public void onPrimaryItemClick(LinkagePrimaryViewHolder holder, View view, String title) {
+ SnackbarUtils.Short(view, title).show();
+ }
+
+ @Override
+ public void onSecondaryItemClick(LinkageSecondaryViewHolder holder, ViewGroup view, BaseGroupedItem item) {
+ SnackbarUtils.Short(view, item.info.getTitle()).show();
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/LinkageRecyclerViewElemeFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/LinkageRecyclerViewElemeFragment.java
new file mode 100644
index 00000000..964e8592
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/LinkageRecyclerViewElemeFragment.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.expands.linkage;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.kunminx.linkage.LinkageRecyclerView;
+import com.kunminx.linkage.adapter.viewholder.LinkagePrimaryViewHolder;
+import com.kunminx.linkage.adapter.viewholder.LinkageSecondaryViewHolder;
+import com.kunminx.linkage.bean.BaseGroupedItem;
+import com.xuexiang.xaop.annotation.SingleClick;
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.utils.SnackbarUtils;
+import com.xuexiang.xui.widget.actionbar.TitleBar;
+import com.xuexiang.xuidemo.DemoDataProvider;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.base.BaseFragment;
+import com.xuexiang.xuidemo.fragment.expands.linkage.custom.CustomLinkagePrimaryAdapterConfig;
+import com.xuexiang.xuidemo.fragment.expands.linkage.eleme.ElemeGroupedItem;
+import com.xuexiang.xuidemo.fragment.expands.linkage.eleme.ElemeSecondaryAdapterConfig;
+
+import butterknife.BindView;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-25 23:20
+ */
+@Page(name = "仿饿了么双列表联动菜单")
+public class LinkageRecyclerViewElemeFragment extends BaseFragment implements CustomLinkagePrimaryAdapterConfig.OnPrimaryItemClickListener, ElemeSecondaryAdapterConfig.OnSecondaryItemClickListener {
+
+ @BindView(R.id.linkage)
+ LinkageRecyclerView linkage;
+
+ /**
+ * 布局的资源id
+ *
+ * @return
+ */
+ @Override
+ protected int getLayoutId() {
+ return R.layout.fragment_linkage_recyclerview;
+ }
+
+ @Override
+ protected TitleBar initTitle() {
+ TitleBar titleBar = super.initTitle();
+ titleBar.addAction(new TitleBar.TextAction("切换") {
+ @SingleClick
+ @Override
+ public void performAction(View view) {
+ if (linkage != null) {
+ linkage.setGridMode(!linkage.isGridMode());
+ }
+ }
+ });
+ return titleBar;
+ }
+
+ /**
+ * 初始化控件
+ */
+ @Override
+ protected void initViews() {
+ linkage.init(DemoDataProvider.getElemeGroupItems(), new CustomLinkagePrimaryAdapterConfig(this), new ElemeSecondaryAdapterConfig(this));
+ }
+
+ @Override
+ public void onPrimaryItemClick(LinkagePrimaryViewHolder holder, View view, String title) {
+ SnackbarUtils.Short(view, title).show();
+ }
+
+ @Override
+ public void onSecondaryItemClick(LinkageSecondaryViewHolder holder, ViewGroup view, BaseGroupedItem item) {
+ SnackbarUtils.Short(view, item.info.getTitle()).show();
+ }
+
+ @Override
+ public void onGoodAdd(View view, BaseGroupedItem item) {
+ SnackbarUtils.Short(view, "添加:" + item.info.getTitle()).show();
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/LinkageRecyclerViewSimpleFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/LinkageRecyclerViewSimpleFragment.java
new file mode 100644
index 00000000..fb0fc0aa
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/LinkageRecyclerViewSimpleFragment.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.expands.linkage;
+
+import android.view.View;
+
+import com.kunminx.linkage.LinkageRecyclerView;
+import com.xuexiang.xaop.annotation.SingleClick;
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.utils.SnackbarUtils;
+import com.xuexiang.xui.widget.actionbar.TitleBar;
+import com.xuexiang.xuidemo.DemoDataProvider;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.base.BaseFragment;
+
+import butterknife.BindView;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-25 11:36
+ */
+@Page(name = "双列表简单使用")
+public class LinkageRecyclerViewSimpleFragment extends BaseFragment {
+ @BindView(R.id.linkage)
+ LinkageRecyclerView linkage;
+
+ /**
+ * 布局的资源id
+ *
+ * @return
+ */
+ @Override
+ protected int getLayoutId() {
+ return R.layout.fragment_linkage_recyclerview;
+ }
+
+ @Override
+ protected TitleBar initTitle() {
+ TitleBar titleBar = super.initTitle();
+ titleBar.addAction(new TitleBar.TextAction("切换") {
+ @SingleClick
+ @Override
+ public void performAction(View view) {
+ if (linkage != null) {
+ linkage.setGridMode(!linkage.isGridMode());
+ }
+ }
+ });
+ return titleBar;
+ }
+
+ /**
+ * 初始化控件
+ */
+ @Override
+ protected void initViews() {
+ linkage.init(DemoDataProvider.getGroupItems());
+ linkage.setScrollSmoothly(true);
+ linkage.setDefaultOnItemBindListener(
+ (primaryHolder, primaryClickView, title) -> {
+ //一级列表点击
+ SnackbarUtils.Short(primaryClickView, title).show();
+ },
+ (primaryHolder, title) -> {
+ //一级列表样式设置
+ //TODO
+
+ },
+ (secondaryHolder, item) -> {
+ //二级列表点击
+ secondaryHolder.getView(R.id.level_2_item).setOnClickListener(v -> {
+ SnackbarUtils.Short(v, item.info.getTitle()).show();
+ });
+ },
+ (headerHolder, item) -> {
+ //TODO
+ },
+ (footerHolder, item) -> {
+ //TODO
+ }
+ );
+ }
+
+
+
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomGroupedItem.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomGroupedItem.java
new file mode 100644
index 00000000..70ce336a
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomGroupedItem.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.expands.linkage.custom;
+
+import com.kunminx.linkage.bean.BaseGroupedItem;
+
+/**
+ * 自定义组
+ *
+ * @author xuexiang
+ * @since 2019-11-25 17:15
+ */
+public class CustomGroupedItem extends BaseGroupedItem {
+
+ public CustomGroupedItem(boolean isHeader, String header) {
+ super(isHeader, header);
+ }
+
+ public CustomGroupedItem(ItemInfo item) {
+ super(item);
+ }
+
+ public static class ItemInfo extends BaseGroupedItem.ItemInfo {
+ private String content;
+ private String imgUrl;
+ private String cost;
+
+ public ItemInfo(String title, String group, String content) {
+ super(title, group);
+ this.content = content;
+ }
+
+ public ItemInfo(String title, String group, String content, String imgUrl) {
+ this(title, group, content);
+ this.imgUrl = imgUrl;
+ }
+
+ public ItemInfo(String title, String group, String content, String imgUrl, String cost) {
+ this(title, group, content, imgUrl);
+ this.cost = cost;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public String getImgUrl() {
+ return imgUrl;
+ }
+
+ public void setImgUrl(String imgUrl) {
+ this.imgUrl = imgUrl;
+ }
+
+ public String getCost() {
+ return cost;
+ }
+
+ public void setCost(String cost) {
+ this.cost = cost;
+ }
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkagePrimaryAdapterConfig.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkagePrimaryAdapterConfig.java
new file mode 100644
index 00000000..f1b42cd4
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkagePrimaryAdapterConfig.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.expands.linkage.custom;
+
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.core.content.ContextCompat;
+
+import com.kunminx.linkage.adapter.viewholder.LinkagePrimaryViewHolder;
+import com.kunminx.linkage.contract.ILinkagePrimaryAdapterConfig;
+import com.xuexiang.xuidemo.R;
+
+/**
+ * 自定义主菜单适配器
+ *
+ * @author xuexiang
+ * @since 2019-11-25 17:17
+ */
+public class CustomLinkagePrimaryAdapterConfig implements ILinkagePrimaryAdapterConfig {
+
+ private static final int MARQUEE_REPEAT_LOOP_MODE = -1;
+ private static final int MARQUEE_REPEAT_NONE_MODE = 0;
+ private Context mContext;
+ private OnPrimaryItemClickListener mItemClickListener;
+
+ public CustomLinkagePrimaryAdapterConfig(OnPrimaryItemClickListener itemClickListener) {
+ mItemClickListener = itemClickListener;
+ }
+
+ public CustomLinkagePrimaryAdapterConfig setOnItemClickListner(OnPrimaryItemClickListener itemClickListener) {
+ mItemClickListener = itemClickListener;
+ return this;
+ }
+
+ @Override
+ public void setContext(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public int getLayoutId() {
+ return R.layout.default_adapter_linkage_primary;
+ }
+
+ @Override
+ public int getGroupTitleViewId() {
+ return R.id.tv_group;
+ }
+
+ @Override
+ public int getRootViewId() {
+ return R.id.layout_group;
+ }
+
+ @Override
+ public void onBindViewHolder(LinkagePrimaryViewHolder holder, boolean selected, String title) {
+ TextView tvTitle = ((TextView) holder.mGroupTitle);
+ tvTitle.setText(title);
+
+ tvTitle.setBackgroundColor(mContext.getResources().getColor(selected ? R.color.colorAccent : R.color.colorWhite));
+ tvTitle.setTextColor(ContextCompat.getColor(mContext, selected ? R.color.colorWhite : R.color.colorGray));
+ tvTitle.setEllipsize(selected ? TextUtils.TruncateAt.MARQUEE : TextUtils.TruncateAt.END);
+ tvTitle.setFocusable(selected);
+ tvTitle.setFocusableInTouchMode(selected);
+ tvTitle.setMarqueeRepeatLimit(selected ? MARQUEE_REPEAT_LOOP_MODE : MARQUEE_REPEAT_NONE_MODE);
+ }
+
+ @Override
+ public void onItemClick(LinkagePrimaryViewHolder holder, View view, String title) {
+ if (mItemClickListener != null) {
+ mItemClickListener.onPrimaryItemClick(holder, view, title);
+ }
+ }
+
+ public interface OnPrimaryItemClickListener {
+ /**
+ * we suggest you get position by holder.getAdapterPosition
+ *
+ * @param holder primaryHolder
+ * @param view view
+ * @param title groupTitle
+ */
+ void onPrimaryItemClick(LinkagePrimaryViewHolder holder, View view, String title);
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkageSecondaryAdapterConfig.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkageSecondaryAdapterConfig.java
new file mode 100644
index 00000000..ab741341
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkageSecondaryAdapterConfig.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.expands.linkage.custom;
+
+
+import android.content.Context;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.kunminx.linkage.adapter.viewholder.LinkageSecondaryFooterViewHolder;
+import com.kunminx.linkage.adapter.viewholder.LinkageSecondaryHeaderViewHolder;
+import com.kunminx.linkage.adapter.viewholder.LinkageSecondaryViewHolder;
+import com.kunminx.linkage.bean.BaseGroupedItem;
+import com.kunminx.linkage.contract.ILinkageSecondaryAdapterConfig;
+import com.xuexiang.xuidemo.R;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-25 17:17
+ */
+public class CustomLinkageSecondaryAdapterConfig implements ILinkageSecondaryAdapterConfig {
+
+ private Context mContext;
+ private OnSecondaryItemClickListener mItemClickListener;
+ private static final int SPAN_COUNT = 2;
+
+ public CustomLinkageSecondaryAdapterConfig(OnSecondaryItemClickListener itemClickListener) {
+ mItemClickListener = itemClickListener;
+ }
+
+ public CustomLinkageSecondaryAdapterConfig setOnItemClickListner(OnSecondaryItemClickListener itemClickListener) {
+ mItemClickListener = itemClickListener;
+ return this;
+ }
+
+ @Override
+ public void setContext(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public int getGridLayoutId() {
+ return R.layout.default_adapter_linkage_secondary_grid;
+ }
+
+ @Override
+ public int getLinearLayoutId() {
+ return R.layout.default_adapter_linkage_secondary_linear;
+ }
+
+ @Override
+ public int getHeaderLayoutId() {
+ return R.layout.default_adapter_linkage_secondary_header;
+ }
+
+ @Override
+ public int getFooterLayoutId() {
+ return R.layout.adapter_linkage_empty_footer;
+ }
+
+ @Override
+ public int getHeaderTextViewId() {
+ return R.id.secondary_header;
+ }
+
+ @Override
+ public int getSpanCountOfGridMode() {
+ return SPAN_COUNT;
+ }
+
+ @Override
+ public void onBindViewHolder(final LinkageSecondaryViewHolder holder,
+ final BaseGroupedItem item) {
+
+ ((TextView) holder.getView(R.id.level_2_title)).setText(item.info.getTitle());
+ ((TextView) holder.getView(R.id.level_2_content)).setText(item.info.getContent());
+
+ ViewGroup viewGroup = holder.getView(R.id.level_2_item);
+ viewGroup.setOnClickListener(v -> {
+ if (mItemClickListener != null) {
+ mItemClickListener.onSecondaryItemClick(holder, viewGroup, item);
+ }
+ });
+
+ }
+
+ @Override
+ public void onBindHeaderViewHolder(LinkageSecondaryHeaderViewHolder holder,
+ BaseGroupedItem item) {
+ ((TextView) holder.getView(R.id.secondary_header)).setText(item.header);
+ }
+
+ @Override
+ public void onBindFooterViewHolder(LinkageSecondaryFooterViewHolder holder,
+ BaseGroupedItem item) {
+ }
+
+ public interface OnSecondaryItemClickListener {
+ /**
+ * we suggest you get position by holder.getAdapterPosition
+ *
+ * @param holder primaryHolder
+ * @param item 内容
+ */
+ void onSecondaryItemClick(LinkageSecondaryViewHolder holder, ViewGroup view, BaseGroupedItem item);
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/eleme/ElemeGroupedItem.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/eleme/ElemeGroupedItem.java
new file mode 100644
index 00000000..1dbcb57b
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/eleme/ElemeGroupedItem.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.expands.linkage.eleme;
+
+import com.kunminx.linkage.bean.BaseGroupedItem;
+
+/**
+ * 饿了么列表简单演示
+ *
+ * @author xuexiang
+ * @since 2019-11-25 22:52
+ */
+public class ElemeGroupedItem extends BaseGroupedItem {
+
+ public ElemeGroupedItem(boolean isHeader, String header) {
+ super(isHeader, header);
+ }
+
+ public ElemeGroupedItem(ItemInfo item) {
+ super(item);
+ }
+
+ public static class ItemInfo extends BaseGroupedItem.ItemInfo {
+ private String content;
+ private String imgUrl;
+ private String cost;
+
+ public ItemInfo(String title, String group, String content) {
+ super(title, group);
+ this.content = content;
+ }
+
+ public ItemInfo(String title, String group, String content, String imgUrl) {
+ this(title, group, content);
+ this.imgUrl = imgUrl;
+ }
+
+ public ItemInfo(String title, String group, String content, String imgUrl, String cost) {
+ this(title, group, content, imgUrl);
+ this.cost = cost;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public String getImgUrl() {
+ return imgUrl;
+ }
+
+ public void setImgUrl(String imgUrl) {
+ this.imgUrl = imgUrl;
+ }
+
+ public String getCost() {
+ return cost;
+ }
+
+ public void setCost(String cost) {
+ this.cost = cost;
+ }
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/eleme/ElemeSecondaryAdapterConfig.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/eleme/ElemeSecondaryAdapterConfig.java
new file mode 100644
index 00000000..e2ea7079
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/eleme/ElemeSecondaryAdapterConfig.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.expands.linkage.eleme;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.kunminx.linkage.adapter.viewholder.LinkageSecondaryFooterViewHolder;
+import com.kunminx.linkage.adapter.viewholder.LinkageSecondaryHeaderViewHolder;
+import com.kunminx.linkage.adapter.viewholder.LinkageSecondaryViewHolder;
+import com.kunminx.linkage.bean.BaseGroupedItem;
+import com.kunminx.linkage.contract.ILinkageSecondaryAdapterConfig;
+import com.xuexiang.xuidemo.R;
+
+/**
+ * 饿了么列表适配器
+ *
+ * @author xuexiang
+ * @since 2019-11-25 22:54
+ */
+public class ElemeSecondaryAdapterConfig implements ILinkageSecondaryAdapterConfig {
+
+ private static final int SPAN_COUNT = 2;
+
+ private Context mContext;
+
+ private OnSecondaryItemClickListener mItemClickListener;
+
+ public ElemeSecondaryAdapterConfig(OnSecondaryItemClickListener itemClickListener) {
+ mItemClickListener = itemClickListener;
+ }
+
+ public ElemeSecondaryAdapterConfig setOnItemClickListner(OnSecondaryItemClickListener itemClickListener) {
+ mItemClickListener = itemClickListener;
+ return this;
+ }
+
+ @Override
+ public void setContext(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public int getGridLayoutId() {
+ return R.layout.adapter_eleme_secondary_grid;
+ }
+
+ @Override
+ public int getLinearLayoutId() {
+ return R.layout.adapter_eleme_secondary_linear;
+ }
+
+
+ @Override
+ public int getHeaderLayoutId() {
+ return R.layout.default_adapter_linkage_secondary_header;
+ }
+
+ @Override
+ public int getFooterLayoutId() {
+ return R.layout.adapter_linkage_empty_footer;
+ }
+
+ @Override
+ public int getHeaderTextViewId() {
+ return R.id.secondary_header;
+ }
+
+ @Override
+ public int getSpanCountOfGridMode() {
+ return SPAN_COUNT;
+ }
+
+ @Override
+ public void onBindViewHolder(final LinkageSecondaryViewHolder holder,
+ final BaseGroupedItem item) {
+
+ ((TextView) holder.getView(R.id.iv_goods_name)).setText(item.info.getTitle());
+ Glide.with(mContext).load(item.info.getImgUrl()).into((ImageView) holder.getView(R.id.iv_goods_img));
+
+ ViewGroup viewGroup = holder.getView(R.id.iv_goods_item);
+ viewGroup.setOnClickListener(v -> {
+ if (mItemClickListener != null) {
+ mItemClickListener.onSecondaryItemClick(holder, viewGroup, item);
+ }
+ });
+
+ holder.getView(R.id.iv_goods_add).setOnClickListener(v -> {
+ if (mItemClickListener != null) {
+ mItemClickListener.onGoodAdd(v, item);
+ }
+ });
+ }
+
+ @Override
+ public void onBindHeaderViewHolder(LinkageSecondaryHeaderViewHolder holder,
+ BaseGroupedItem item) {
+
+ ((TextView) holder.getView(R.id.secondary_header)).setText(item.header);
+ }
+
+ @Override
+ public void onBindFooterViewHolder(LinkageSecondaryFooterViewHolder holder,
+ BaseGroupedItem item) {
+
+ }
+
+
+ public interface OnSecondaryItemClickListener {
+
+ void onSecondaryItemClick(LinkageSecondaryViewHolder holder, ViewGroup view, BaseGroupedItem item);
+
+ void onGoodAdd(View view, BaseGroupedItem item);
+
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/qrcode/CustomCaptureActivity.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/qrcode/CustomCaptureActivity.java
index ffe0a7be..d427d303 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/qrcode/CustomCaptureActivity.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/qrcode/CustomCaptureActivity.java
@@ -33,8 +33,8 @@
import com.xuexiang.xuidemo.R;
import com.xuexiang.xuidemo.utils.XToastUtils;
-import static com.xuexiang.xuidemo.base.webview.MiddlewareWebViewClient.APP_LINK_ACTION;
-import static com.xuexiang.xuidemo.base.webview.MiddlewareWebViewClient.APP_LINK_HOST;
+import static com.xuexiang.xuidemo.base.webview.WebViewInterceptDialog.APP_LINK_ACTION;
+import static com.xuexiang.xuidemo.base.webview.WebViewInterceptDialog.APP_LINK_HOST;
/**
* 自定义二维码扫描界面
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/utils/ViewUtilsFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/utils/ViewUtilsFragment.java
index f6dded43..8fe7b30a 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/utils/ViewUtilsFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/utils/ViewUtilsFragment.java
@@ -19,6 +19,7 @@
import com.xuexiang.xpage.annotation.Page;
import com.xuexiang.xuidemo.R;
import com.xuexiang.xuidemo.base.ComponentContainerFragment;
+import com.xuexiang.xuidemo.fragment.utils.view.ObjectAnimationFragment;
import com.xuexiang.xuidemo.fragment.utils.view.ViewAnimationFragment;
import com.xuexiang.xuidemo.fragment.utils.view.ViewPaddingFragment;
@@ -32,7 +33,8 @@ public class ViewUtilsFragment extends ComponentContainerFragment {
protected Class[] getPagesClasses() {
return new Class[]{
ViewAnimationFragment.class,
- ViewPaddingFragment.class
+ ViewPaddingFragment.class,
+ ObjectAnimationFragment.class
};
}
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/utils/view/ObjectAnimationFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/utils/view/ObjectAnimationFragment.java
new file mode 100644
index 00000000..5904b0bb
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/utils/view/ObjectAnimationFragment.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.utils.view;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
+import android.graphics.PointF;
+import android.view.View;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.AnticipateInterpolator;
+import android.view.animation.AnticipateOvershootInterpolator;
+import android.view.animation.BounceInterpolator;
+import android.view.animation.CycleInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.LinearInterpolator;
+import android.view.animation.OvershootInterpolator;
+import android.widget.TextView;
+
+import com.xuexiang.xaop.annotation.SingleClick;
+import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.base.BaseFragment;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+/**
+ * ObjectAnimator 对象动画
+ * ValueAnimator 值动画
+ * PropertyValueHolder 用于同时执行多个动画
+ * TypeEvaluator 估值器
+ * AnimatorSet 动画集合
+ * Interpolator 差值器(已经预先定义好的估值器)
+ *
+ * @author xuexiang
+ * @since 2019-11-30 17:29
+ */
+@Page(name = "属性动画")
+public class ObjectAnimationFragment extends BaseFragment {
+
+ @BindView(R.id.tv_content)
+ TextView tvContent;
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.fragment_object_animation;
+ }
+
+ @Override
+ protected void initViews() {
+
+ }
+
+ @SingleClick
+ @OnClick({R.id.btn_alpha, R.id.btn_translation, R.id.btn_scale, R.id.btn_rotation, R.id.btn_value_animator, R.id.btn_type_evaluator, R.id.btn_compose1, R.id.btn_compose2})
+ public void onViewClicked(View view) {
+ switch (view.getId()) {
+ case R.id.btn_alpha:
+ doAlphaAnimation(tvContent);
+ break;
+ case R.id.btn_translation:
+ doTranslationAnimation(tvContent);
+ break;
+ case R.id.btn_scale:
+ doScaleAnimation(tvContent);
+ break;
+ case R.id.btn_rotation:
+ doRotationAnimation(tvContent);
+ break;
+ case R.id.btn_value_animator:
+ doValueAnimator(tvContent);
+ break;
+ case R.id.btn_type_evaluator:
+ doTypeEvaluator(tvContent);
+ break;
+ case R.id.btn_compose1:
+ doComposeAnimation1(tvContent);
+ break;
+ case R.id.btn_compose2:
+ doComposeAnimation2(tvContent);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * 透明度动画
+ *
+ * @param view
+ */
+ private void doAlphaAnimation(View view) {
+ ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 1, 0, 1);
+ animator.setDuration(2000);
+ animator.start();
+ }
+
+ /**
+ * 平移动画
+ *
+ * @param view
+ */
+ private void doTranslationAnimation(View view) {
+ ObjectAnimator animatorX = ObjectAnimator.ofFloat(view, "translationX", 0, 200, 0, -200, 0);
+ ObjectAnimator animatorY = ObjectAnimator.ofFloat(view, "translationY", 0, 200, 0, -200, 0);
+ AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.play(animatorX).before(animatorY);
+ animatorSet.setDuration(2000);
+ animatorSet.start();
+ }
+
+ /**
+ * 缩放动画
+ *
+ * @param view
+ */
+ private void doScaleAnimation(View view) {
+ ObjectAnimator animatorX = ObjectAnimator.ofFloat(view, "scaleX", 1F, 0.5F, 1F, 1.5F, 1F);
+ ObjectAnimator animatorY = ObjectAnimator.ofFloat(view, "scaleY", 1F, 0.5F, 1F, 1.5F, 1F);
+ AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.play(animatorX).with(animatorY);
+ animatorSet.setDuration(2000);
+ animatorSet.start();
+ }
+
+ /**
+ * 旋转动画
+ *
+ * @param view
+ */
+ private void doRotationAnimation(View view) {
+ ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotation", 0, 360, 0);
+ animator.setDuration(2000);
+ //加速查值器,参数越大,速度越来越快
+ animator.setInterpolator(new AccelerateInterpolator(2));
+// //减速差值起,和上面相反
+// animator.setInterpolator(new DecelerateInterpolator(10));
+// //先加速后减速插值器
+// animator.setInterpolator(new AccelerateDecelerateInterpolator());
+// //张力值,默认为2,T越大,初始的偏移越大,而且速度越快
+// animator.setInterpolator(new AnticipateInterpolator(3));
+// //张力值tension,默认为2,张力越大,起始时和结束时的偏移越大
+// animator.setInterpolator(new AnticipateOvershootInterpolator(6));
+// //弹跳插值器
+// animator.setInterpolator(new BounceInterpolator());
+// //周期插值器
+// animator.setInterpolator(new CycleInterpolator(2));
+// //线性差值器,匀速
+// animator.setInterpolator(new LinearInterpolator());
+// //张力插值器,扩散反弹一下
+// animator.setInterpolator(new OvershootInterpolator(2));
+ animator.start();
+ }
+
+
+ /**
+ * 值动画,适合构建复杂的动画
+ *
+ * @param view
+ */
+ private void doValueAnimator(View view) {
+ //值的变化,与控件无关
+ ValueAnimator animator = ValueAnimator.ofFloat(1, 0, 1);
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float value = (float) animation.getAnimatedValue();
+ view.setScaleX(value);
+ view.setScaleY(value);
+ view.setAlpha(value);
+ view.setRotation(360 * (1 - value));
+ }
+ });
+ animator.setDuration(2000).start();
+ }
+
+
+ /**
+ * 估值器(实现重力下落的效果)
+ *
+ * @param view
+ */
+ private void doTypeEvaluator(final View view) {
+ ValueAnimator animator = new ValueAnimator();
+ animator.setDuration(3000);
+ animator.setObjectValues(new PointF(0, 0));
+ final PointF pointF = new PointF();
+ animator.setEvaluator(new TypeEvaluator() {
+ @Override
+ public Object evaluate(float fraction, Object startValue, Object endValue) {
+ //fraction是运动中的匀速变化的值
+ //根据重力计算实际的运动y=vt=0.5*g*t*t
+ //g越大效果越明显
+ pointF.x = 100 * (fraction * 5);
+ pointF.y = 0.5f * 300f * (fraction * 5) * (fraction * 5);
+ return pointF;
+ }
+ });
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ PointF p = (PointF) animation.getAnimatedValue();
+ view.setX(p.x);
+ view.setY(p.y);
+ }
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ //还原到原始的位置
+ view.setTranslationX(0);
+ view.setTranslationY(0);
+ }
+ });
+ animator.start();
+ }
+
+
+ /**
+ * 组合动画
+ *
+ * @param view
+ */
+ private void doComposeAnimation1(View view) {
+ ObjectAnimator alpha = ObjectAnimator.ofFloat(view, "alpha", 1, 0, 1);
+ ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1, 0, 1);
+ ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1, 0, 1);
+ ObjectAnimator rotation = ObjectAnimator.ofFloat(view, "rotation", 0, 360, 0);
+
+ AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.play(alpha).with(scaleX).with(scaleY).with(rotation);
+ animatorSet.setDuration(2000).start();
+ }
+
+
+ /**
+ * 组合动画
+ *
+ * @param view
+ */
+ private void doComposeAnimation2(View view) {
+ PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1, 0, 1);
+ PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1, 0, 1);
+ PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1, 0, 1);
+ PropertyValuesHolder rotation = PropertyValuesHolder.ofFloat("rotation", 0, 360, 0);
+
+ ValueAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, alpha, scaleX, scaleY, rotation);
+ animator.setDuration(2000).start();
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/utils/TokenUtils.java b/app/src/main/java/com/xuexiang/xuidemo/utils/TokenUtils.java
new file mode 100644
index 00000000..eff55e31
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/utils/TokenUtils.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xuidemo.utils;
+
+import android.content.Context;
+
+import com.tencent.mmkv.MMKV;
+import com.umeng.analytics.MobclickAgent;
+import com.xuexiang.xuidemo.activity.LoginActivity;
+import com.xuexiang.xutil.app.ActivityUtils;
+import com.xuexiang.xutil.common.StringUtils;
+
+/**
+ * Token管理工具
+ *
+ * @author xuexiang
+ * @since 2019-11-17 22:37
+ */
+public final class TokenUtils {
+
+ private static String sToken;
+
+ private static final String KEY_TOKEN = "com.xuexiang.xuidemo.utils.KEY_TOKEN";
+
+ private TokenUtils() {
+ throw new UnsupportedOperationException("u can't instantiate me...");
+ }
+
+ /**
+ * 初始化Token信息
+ */
+ public static void init(Context context) {
+ MMKV.initialize(context);
+ sToken = MMKV.defaultMMKV().decodeString(KEY_TOKEN, "");
+ }
+
+ public static void setToken(String token) {
+ sToken = token;
+ MMKV.defaultMMKV().putString(KEY_TOKEN, token);
+ }
+
+ public static void clearToken() {
+ sToken = null;
+ MMKV.defaultMMKV().remove(KEY_TOKEN);
+ }
+
+ public static boolean hasToken() {
+ return MMKV.defaultMMKV().containsKey(KEY_TOKEN);
+ }
+
+ /**
+ * 处理登录成功的事件
+ *
+ * @param token 账户信息
+ */
+ public static boolean handleLoginSuccess(String token) {
+ if (!StringUtils.isEmpty(token)) {
+ XToastUtils.success("登录成功!");
+ MobclickAgent.onProfileSignIn("github", token);
+ setToken(token);
+ return true;
+ } else {
+ XToastUtils.error("登录失败!");
+ return false;
+ }
+ }
+
+ /**
+ * 处理登出的事件
+ */
+ public static void handleLogoutSuccess() {
+ MobclickAgent.onProfileSignOff();
+ //登出时,清除账号信息
+ clearToken();
+ XToastUtils.success("登出成功!");
+ //跳转到登录页
+ ActivityUtils.startActivity(LoginActivity.class);
+ }
+
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/utils/Utils.java b/app/src/main/java/com/xuexiang/xuidemo/utils/Utils.java
index e3e95d53..a80394f5 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/utils/Utils.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/utils/Utils.java
@@ -35,6 +35,8 @@
import com.xuexiang.xutil.file.FileIOUtils;
import com.xuexiang.xutil.file.FileUtils;
+import java.io.File;
+
import static com.xuexiang.xuidemo.base.webview.AgentWebFragment.KEY_URL;
/**
@@ -142,12 +144,14 @@ public static PictureSelectionModel getPictureSelector(Activity activity) {
/**
* 处理拍照的回调
+ *
* @param data
* @return
*/
public static String handleOnPictureTaken(byte[] data) {
return handleOnPictureTaken(data, JPEG);
}
+
/**
* 处理拍照的回调
*
@@ -160,6 +164,10 @@ public static String handleOnPictureTaken(byte[] data, String fileSuffix) {
return result ? picPath : "";
}
+ public static String getImageSavePath() {
+ return FileUtils.getDiskCacheDir("images") + File.separator + DateUtils.getNowMills() + JPEG;
+ }
+
//==========截图===========//
/**
diff --git a/app/src/main/java/com/xuexiang/xuidemo/utils/XToastUtils.java b/app/src/main/java/com/xuexiang/xuidemo/utils/XToastUtils.java
index a1cf18d5..51173576 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/utils/XToastUtils.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/utils/XToastUtils.java
@@ -70,6 +70,11 @@ public static void error(@NonNull CharSequence message) {
XToast.error(XUI.getContext(), message).show();
}
+ @MainThread
+ public static void error(@NonNull Exception error) {
+ XToast.error(XUI.getContext(), error.getMessage()).show();
+ }
+
@MainThread
public static void error(@StringRes int message) {
XToast.error(XUI.getContext(), message).show();
diff --git a/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/XBasicLibInit.java b/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/XBasicLibInit.java
index 6a78b123..aa0f5d09 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/XBasicLibInit.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/XBasicLibInit.java
@@ -27,6 +27,7 @@
import com.xuexiang.xuidemo.MyApp;
import com.xuexiang.xuidemo.base.BaseActivity;
import com.xuexiang.xuidemo.utils.LocationService;
+import com.xuexiang.xuidemo.utils.TokenUtils;
import com.xuexiang.xuidemo.utils.XToastUtils;
import com.xuexiang.xutil.XUtil;
import com.xuexiang.xutil.common.StringUtils;
@@ -65,6 +66,7 @@ private static void initUtils(Application application) {
XUtil.debug(MyApp.isDebug());
//百度定位
LocationService.get().init(application);
+ TokenUtils.init(application);
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/widget/iconfont/XUIIconFont.java b/app/src/main/java/com/xuexiang/xuidemo/widget/iconfont/XUIIconFont.java
index 09b81f1a..bcaa11c1 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/widget/iconfont/XUIIconFont.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/widget/iconfont/XUIIconFont.java
@@ -36,7 +36,7 @@
import java.util.Map;
/**
- * XUI字体图标库
+ * XUI字体图标库,是使用 平台自动生成的
*
* @author xuexiang
* @since 2019-10-13 16:29
diff --git a/app/src/main/res/color/selector_round_button_main_theme_color.xml b/app/src/main/res/color/selector_round_button_main_theme_color.xml
new file mode 100644
index 00000000..16fd2c79
--- /dev/null
+++ b/app/src/main/res/color/selector_round_button_main_theme_color.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-hdpi/ic_expand_linkage_list.png b/app/src/main/res/drawable-hdpi/ic_expand_linkage_list.png
new file mode 100644
index 00000000..97dd5f34
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_expand_linkage_list.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/bg_food_sample.png b/app/src/main/res/drawable-xxhdpi/bg_food_sample.png
new file mode 100644
index 00000000..3fbfc906
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/bg_food_sample.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/btn_add_food.png b/app/src/main/res/drawable-xxhdpi/btn_add_food.png
new file mode 100644
index 00000000..20843773
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/btn_add_food.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/tag_new_good.png b/app/src/main/res/drawable-xxhdpi/tag_new_good.png
new file mode 100644
index 00000000..ef42dec2
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/tag_new_good.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_chevron_right_black_48dp.png b/app/src/main/res/drawable-xxxhdpi/ic_chevron_right_black_48dp.png
new file mode 100644
index 00000000..2ba0db98
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_chevron_right_black_48dp.png differ
diff --git a/app/src/main/res/drawable/custom_vcet_shape_bg_focus.xml b/app/src/main/res/drawable/custom_vcet_shape_bg_focus.xml
new file mode 100644
index 00000000..f93a979b
--- /dev/null
+++ b/app/src/main/res/drawable/custom_vcet_shape_bg_focus.xml
@@ -0,0 +1,28 @@
+
+
+ -
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/custom_vcet_shape_bg_normal.xml b/app/src/main/res/drawable/custom_vcet_shape_bg_normal.xml
new file mode 100644
index 00000000..cb6f615e
--- /dev/null
+++ b/app/src/main/res/drawable/custom_vcet_shape_bg_normal.xml
@@ -0,0 +1,27 @@
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_arrow_right.xml b/app/src/main/res/drawable/ic_arrow_right.xml
new file mode 100644
index 00000000..86de623b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_arrow_right.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_checked_right.xml b/app/src/main/res/drawable/ic_checked_right.xml
new file mode 100644
index 00000000..7d14f949
--- /dev/null
+++ b/app/src/main/res/drawable/ic_checked_right.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_login_close.xml b/app/src/main/res/drawable/ic_login_close.xml
new file mode 100644
index 00000000..178ac091
--- /dev/null
+++ b/app/src/main/res/drawable/ic_login_close.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_password.xml b/app/src/main/res/drawable/ic_password.xml
new file mode 100644
index 00000000..716e402a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_password.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_phone.xml b/app/src/main/res/drawable/ic_phone.xml
new file mode 100644
index 00000000..56cf551f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_phone.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/app/src/main/res/drawable/selector_bg_tag_stroke.xml b/app/src/main/res/drawable/selector_bg_tag_stroke.xml
new file mode 100644
index 00000000..89540df1
--- /dev/null
+++ b/app/src/main/res/drawable/selector_bg_tag_stroke.xml
@@ -0,0 +1,40 @@
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_camera.xml b/app/src/main/res/layout/activity_camera.xml
index 59087b41..639a7a8f 100644
--- a/app/src/main/res/layout/activity_camera.xml
+++ b/app/src/main/res/layout/activity_camera.xml
@@ -1,5 +1,4 @@
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/adapter_drop_down_list_item.xml b/app/src/main/res/layout/adapter_drop_down_list_item.xml
new file mode 100644
index 00000000..96fa46b0
--- /dev/null
+++ b/app/src/main/res/layout/adapter_drop_down_list_item.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/adapter_eleme_secondary_grid.xml b/app/src/main/res/layout/adapter_eleme_secondary_grid.xml
new file mode 100644
index 00000000..c85a661c
--- /dev/null
+++ b/app/src/main/res/layout/adapter_eleme_secondary_grid.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/adapter_eleme_secondary_linear.xml b/app/src/main/res/layout/adapter_eleme_secondary_linear.xml
new file mode 100644
index 00000000..0204cc45
--- /dev/null
+++ b/app/src/main/res/layout/adapter_eleme_secondary_linear.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/adapter_expandable_list_item.xml b/app/src/main/res/layout/adapter_expandable_list_item.xml
new file mode 100644
index 00000000..099f3033
--- /dev/null
+++ b/app/src/main/res/layout/adapter_expandable_list_item.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/adapter_flexbox_layout_item.xml b/app/src/main/res/layout/adapter_flexbox_layout_item.xml
new file mode 100644
index 00000000..3101bde5
--- /dev/null
+++ b/app/src/main/res/layout/adapter_flexbox_layout_item.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/adapter_item_tag.xml b/app/src/main/res/layout/adapter_item_tag.xml
index 41f4b99a..fe904eb1 100644
--- a/app/src/main/res/layout/adapter_item_tag.xml
+++ b/app/src/main/res/layout/adapter_item_tag.xml
@@ -7,7 +7,7 @@
android:id="@+id/tv_tag"
style="@style/TextStyle.Explain"
android:layout_height="32dp"
- android:layout_marginLeft="?attr/xui_config_content_spacing_horizontal"
+ android:layout_marginStart="?attr/xui_config_content_spacing_horizontal"
android:layout_marginTop="?attr/xui_config_content_spacing_horizontal"
android:background="@drawable/bg_rect_round_tag_btn"
android:paddingBottom="5dp"
diff --git a/app/src/main/res/layout/adapter_linkage_empty_footer.xml b/app/src/main/res/layout/adapter_linkage_empty_footer.xml
new file mode 100644
index 00000000..073b6e22
--- /dev/null
+++ b/app/src/main/res/layout/adapter_linkage_empty_footer.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml
index 69b06341..b95e1b24 100644
--- a/app/src/main/res/layout/fragment_about.xml
+++ b/app/src/main/res/layout/fragment_about.xml
@@ -19,52 +19,54 @@
android:layout_height="match_parent"
android:orientation="vertical">
-
+
-
+
-
-
-
-
-
+ android:gravity="center_horizontal"
+ android:orientation="vertical"
+ android:paddingTop="50dp"
+ android:paddingBottom="25dp">
-
+
-
+
+
+
+
+
+
+
+
+
-
+
+
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_drop_down_menu.xml b/app/src/main/res/layout/fragment_drop_down_menu.xml
new file mode 100644
index 00000000..99f1bd2a
--- /dev/null
+++ b/app/src/main/res/layout/fragment_drop_down_menu.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_expandable_horizontal.xml b/app/src/main/res/layout/fragment_expandable_horizontal.xml
new file mode 100644
index 00000000..a474e5d9
--- /dev/null
+++ b/app/src/main/res/layout/fragment_expandable_horizontal.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_expandable_simple.xml b/app/src/main/res/layout/fragment_expandable_simple.xml
new file mode 100644
index 00000000..ab34720d
--- /dev/null
+++ b/app/src/main/res/layout/fragment_expandable_simple.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_flexbox_layout.xml b/app/src/main/res/layout/fragment_flexbox_layout.xml
new file mode 100644
index 00000000..2e8c0f30
--- /dev/null
+++ b/app/src/main/res/layout/fragment_flexbox_layout.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_flowtaglayout.xml b/app/src/main/res/layout/fragment_flowtaglayout.xml
index afbb876f..868c34d9 100644
--- a/app/src/main/res/layout/fragment_flowtaglayout.xml
+++ b/app/src/main/res/layout/fragment_flowtaglayout.xml
@@ -1,4 +1,21 @@
+
+
-
+
-
+
-
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_imageload_strategy.xml b/app/src/main/res/layout/fragment_imageload_strategy.xml
new file mode 100644
index 00000000..c404cd77
--- /dev/null
+++ b/app/src/main/res/layout/fragment_imageload_strategy.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_linkage_recyclerview.xml b/app/src/main/res/layout/fragment_linkage_recyclerview.xml
new file mode 100644
index 00000000..e0a92841
--- /dev/null
+++ b/app/src/main/res/layout/fragment_linkage_recyclerview.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_login.xml b/app/src/main/res/layout/fragment_login.xml
new file mode 100644
index 00000000..9bc85069
--- /dev/null
+++ b/app/src/main/res/layout/fragment_login.xml
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_object_animation.xml b/app/src/main/res/layout/fragment_object_animation.xml
new file mode 100644
index 00000000..466abdaf
--- /dev/null
+++ b/app/src/main/res/layout/fragment_object_animation.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_photo_edit.xml b/app/src/main/res/layout/fragment_photo_edit.xml
index 2abba014..40b6e21c 100644
--- a/app/src/main/res/layout/fragment_photo_edit.xml
+++ b/app/src/main/res/layout/fragment_photo_edit.xml
@@ -61,6 +61,13 @@
android:layout_marginTop="8dp"
android:text="滤镜" />
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_qrcode.xml b/app/src/main/res/layout/fragment_qrcode.xml
index 8cbe1779..64f8d21d 100644
--- a/app/src/main/res/layout/fragment_qrcode.xml
+++ b/app/src/main/res/layout/fragment_qrcode.xml
@@ -19,44 +19,44 @@
android:layout_height="match_parent"
android:orientation="vertical">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_super_click.xml b/app/src/main/res/layout/fragment_super_click.xml
index 246afe42..106b9412 100755
--- a/app/src/main/res/layout/fragment_super_click.xml
+++ b/app/src/main/res/layout/fragment_super_click.xml
@@ -1,95 +1,142 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_supertextview_common_use.xml b/app/src/main/res/layout/fragment_supertextview_common_use.xml
index 8699b4dc..2531fb56 100755
--- a/app/src/main/res/layout/fragment_supertextview_common_use.xml
+++ b/app/src/main/res/layout/fragment_supertextview_common_use.xml
@@ -5,15 +5,9 @@
android:layout_height="match_parent"
android:orientation="vertical">
-
+
-
+
-
-
-
-
-
diff --git a/app/src/main/res/layout/fragment_verify_code_edittext.xml b/app/src/main/res/layout/fragment_verify_code_edittext.xml
index bd0a94d8..d096b7af 100644
--- a/app/src/main/res/layout/fragment_verify_code_edittext.xml
+++ b/app/src/main/res/layout/fragment_verify_code_edittext.xml
@@ -30,10 +30,23 @@
android:layout_height="wrap_content"
app:vcet_is_pwd="true" />
+
+
+ android:layout_marginTop="?attr/xui_config_content_spacing_vertical"
+ android:text="清空" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_view_padding.xml b/app/src/main/res/layout/fragment_view_padding.xml
index 310a01db..794f8c96 100644
--- a/app/src/main/res/layout/fragment_view_padding.xml
+++ b/app/src/main/res/layout/fragment_view_padding.xml
@@ -69,7 +69,6 @@
+ android:max="100"
+ android:progress="20" />
diff --git a/app/src/main/res/layout/layout_common_recycleview.xml b/app/src/main/res/layout/layout_common_recycleview.xml
new file mode 100644
index 00000000..5c9d64d5
--- /dev/null
+++ b/app/src/main/res/layout/layout_common_recycleview.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_drop_down_custom.xml b/app/src/main/res/layout/layout_drop_down_custom.xml
new file mode 100644
index 00000000..7562f8e2
--- /dev/null
+++ b/app/src/main/res/layout/layout_drop_down_custom.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index cb56d4a3..24123da5 100755
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -309,4 +309,51 @@
- 6
+
+ - 不限
+ - 武汉
+ - 北京
+ - 上海
+ - 成都
+ - 广州
+ - 深圳
+ - 重庆
+ - 天津
+ - 西安
+ - 南京
+ - 杭州
+
+
+
+ - 不限
+ - 18岁以下
+ - 18-22岁
+ - 23-26岁
+ - 27-35岁
+ - 35岁以上
+
+
+
+ - 不限
+ - 男
+ - 女
+
+
+
+ - 不限
+ - 白羊座
+ - 金牛座
+ - 双子座
+ - 巨蟹座
+ - 狮子座
+ - 处女座
+ - 天秤座
+ - 天蝎座
+ - 射手座
+ - 摩羯座
+ - 水瓶座
+ - 双鱼座
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index af9057d3..01422020 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -75,4 +75,10 @@
#e488ff
#EE3455
#FFaa89
+
+ #7B1FA2
+ #111111
+ #f2f2f2
+ #9C27B0
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9bf3724a..009e098b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,5 +1,6 @@
XUIDemo
+ XUI浏览器
@@ -9,9 +10,6 @@
请选择
数字必须大于0小于100!
^[1-9]?\\d$
- Invalid mobile number!
- ^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(16[6])|(17[0,1,3,5-8])|(18[0-9])|(19[8,9]))\\d{8}$
-
示例图片
访问官网
@@ -19,6 +17,7 @@
版本更新
GitHub主页
© %1$s xuexiangjys All rights reserved.
+ 加入QQ官方交流群
Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean. A small river named Duden flows by their place and supplies it with the necessary regelialia. It is a paradisematic country, in which roasted parts of sentences fly into your mouth. Even the all-powerful Pointing has no control about the blind texts it is an almost unorthographic life One day however a small line of blind text by the name of Lorem Ipsum decided to leave for the far World of Grammar.
@@ -388,4 +387,32 @@
Flash off
Flash on
+
+ 登录/注册
+ 获取验证码
+
+ 登录
+ 验证码登录
+ 注册
+ 忘记密码?
+ 验证码登录
+ 密码登录
+ 请输入手机号码
+ 手机号码
+ 密码
+ 旧密码
+ 请输入验证码
+ 验证码
+ 密码必须是8~18位字母和数字的组合!
+ 新密码必须是8~18位字母和数字的组合!
+ 无效的手机号!
+ ^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(16[6])|(17[0,1,3,5-8])|(18[0-9])|(19[8,9]))\\d{8}$
+ 请输入4位数验证码
+ ^\\d{4}$
+ ^(?:(?=.*[a-zA-Z])(?=.*[0-9])).{8,18}$
+ 重置密码
+ 点击注册即表示同意
+ ]]>
+
+
diff --git a/app/src/main/res/values/styles_demo.xml b/app/src/main/res/values/styles_demo.xml
index 79995839..3a0c67a8 100644
--- a/app/src/main/res/values/styles_demo.xml
+++ b/app/src/main/res/values/styles_demo.xml
@@ -116,11 +116,13 @@
- 60dp
- left_center
- left_center
- - 25dp
- - 25dp
+ - 15dp
+ - 15dp
- 2dp
- 13sp
- 0dp
+ - 16dp
+ - 16dp
- false
- true
diff --git a/app/src/main/res/values/styles_widget.xml b/app/src/main/res/values/styles_widget.xml
index c532ceaa..acbbd5d9 100644
--- a/app/src/main/res/values/styles_widget.xml
+++ b/app/src/main/res/values/styles_widget.xml
@@ -165,4 +165,29 @@
- @layout/sv_layout_custom
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/README.md b/docs/README.md
index 274f01f0..d0ae6ffe 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -57,10 +57,10 @@ allprojects {
dependencies {
...
//androidx项目
- implementation 'com.github.xuexiangjys:XUI:1.1.0'
+ implementation 'com.github.xuexiangjys:XUI:1.1.1'
implementation 'androidx.appcompat:appcompat:1.1.0'
- implementation 'androidx.recyclerview:recyclerview:1.0.0'
+ implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.material:material:1.1.0-beta01'
implementation 'com.github.bumptech.glide:glide:4.8.0'
}
@@ -159,15 +159,19 @@ protected void attachBaseContext(Context newBase) {
* [QMUI_Android](https://github.com/Tencent/QMUI_Android)
* [AgentWeb](https://github.com/Justson/AgentWeb)
-* [CityPicker](https://github.com/xuexiangjys/CityPicker)
-* [SmartRefreshLayout](https://github.com/scwang90/SmartRefreshLayout)
-* [PictureSelector](https://github.com/LuckSiege/PictureSelector)
+* [Android-Iconics](https://github.com/mikepenz/Android-Iconics)
* [Android-PickerView](https://github.com/Bigkoo/Android-PickerView)
+* [CityPicker](https://github.com/xuexiangjys/CityPicker)
+* [FlycoBanner_Master](https://github.com/H07000223/FlycoBanner_Master)
+* [Linkage-RecyclerView](https://github.com/KunMinX/Linkage-RecyclerView)
* [MaterialEditText](https://github.com/rengwuxian/MaterialEditText)
* [MaterialSpinner](https://github.com/jaredrummler/MaterialSpinner)
-* [FlycoBanner_Master](https://github.com/H07000223/FlycoBanner_Master)
* [MaterialProgressBar](https://github.com/DreaminginCodeZH/MaterialProgressBar)
+* [MPAndroidChart](https://github.com/PhilJay/MPAndroidChart)
+* [PictureSelector](https://github.com/LuckSiege/PictureSelector)
+* [SmartRefreshLayout](https://github.com/scwang90/SmartRefreshLayout)
* [SlideBack](https://github.com/ParfoisMeng/SlideBack)
+* [SwipeRecyclerView](https://github.com/yanzhenjie/SwipeRecyclerView)
## 联系方式
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/adapter/listview/BaseListAdapter.java b/xui_lib/src/main/java/com/xuexiang/xui/adapter/listview/BaseListAdapter.java
index e4c30d91..ee076948 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/adapter/listview/BaseListAdapter.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/adapter/listview/BaseListAdapter.java
@@ -35,11 +35,6 @@ public abstract class BaseListAdapter extends XListAdapter {
public BaseListAdapter(Context context) {
super(context);
}
-
- public BaseListAdapter(Context context, OnListItemListener listener) {
- super(context, listener);
- }
-
public BaseListAdapter(Context context, List data) {
super(context, data);
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/adapter/listview/XListAdapter.java b/xui_lib/src/main/java/com/xuexiang/xui/adapter/listview/XListAdapter.java
index b78745b8..ecdb5df0 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/adapter/listview/XListAdapter.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/adapter/listview/XListAdapter.java
@@ -29,215 +29,210 @@
/**
* 集合列表适配器
- *
- * @author XUE
- *
+ *
* @param
+ * @author XUE
*/
public abstract class XListAdapter extends BaseAdapter {
- private List mData = new ArrayList<>();
- private OnListItemListener mOnListItemListener;
- private Context mContext;
-
- public XListAdapter(Context context) {
- mContext = context;
- }
-
- public XListAdapter(Context context, OnListItemListener callback) {
- this(context);
- mOnListItemListener = callback;
- }
-
- public XListAdapter(Context context, List data) {
- mContext = context;
- setData(data);
- }
-
- public XListAdapter(Context context, T[] data) {
- mContext = context;
- setData(data);
- }
-
- public void setData(List data) {
- if (data != null) {
- mData.clear();
- mData.addAll(data);
- } else {
- mData.clear();
- }
- notifyDataSetChanged();
- }
-
- public void setData(T[] data) {
- if (data != null && data.length > 0) {
- setData(Arrays.asList(data));
- }
- }
-
- public List translateData(T[] data) {
- if (data != null && data.length > 0) {
- List result = new ArrayList<>();
- result.addAll(Arrays.asList(data));
- return result;
- } else {
- return null;
- }
- }
-
- public void addData(List data) {
- if (data != null && data.size() > 0) {
- if (mData == null) {
- mData = new ArrayList<>();
- }
- mData.addAll(data);
- notifyDataSetChanged();
- }
- }
-
- public void addData(T[] data) {
- addData(Arrays.asList(data));
- }
-
- public void addData(T data) {
- if (data != null) {
- if (mData == null) {
- mData = new ArrayList<>();
- }
- mData.add(data);
- notifyDataSetChanged();
- }
- }
-
- public void removeElement(T element) {
- if (mData.contains(element)) {
- mData.remove(element);
- notifyDataSetChanged();
- }
- }
-
- public void removeElement(int position) {
- if (mData != null && mData.size() > position) {
- mData.remove(position);
- notifyDataSetChanged();
- }
- }
-
- public void removeElements(List elements) {
- if (mData != null && elements != null && elements.size() > 0 && mData.size() >= elements.size()) {
- for (T element : elements) {
- if (mData.contains(element)) {
- mData.remove(element);
- }
- }
- notifyDataSetChanged();
- }
- }
-
- public void removeElements(T[] elements) {
- if (elements != null && elements.length > 0) {
- removeElements(Arrays.asList(elements));
- }
- }
-
- public void updateElement(T element, int position) {
- if (position >= 0 && mData.size() > position) {
- mData.remove(position);
- mData.add(position, element);
- notifyDataSetChanged();
- }
- }
-
- public void addElement(T element) {
- if (element != null) {
- if (mData == null) {
- mData = new ArrayList();
- }
- mData.add(element);
- notifyDataSetChanged();
- }
- }
-
- public void clearData() {
- if (mData != null) {
- mData.clear();
- notifyDataSetChanged();
- }
- }
-
- public void clearNotNotify() {
- if (mData != null) {
- mData.clear();
- }
- }
-
- protected void visible(boolean flag, View view) {
- if (flag) {
- view.setVisibility(View.VISIBLE);
- }
- }
-
- protected void gone(boolean flag, View view) {
- if (flag) {
- view.setVisibility(View.GONE);
- }
- }
-
- protected void inVisible(View view) {
- view.setVisibility(View.INVISIBLE);
- }
-
- protected Drawable getDrawable(int resId) {
- return mContext.getResources().getDrawable(resId);
- }
-
- protected String getString(int resId) {
- return mContext.getResources().getString(resId);
- }
-
- protected int getColor(int resId) {
- return mContext.getResources().getColor(resId);
- }
-
- public List getItems() {
- return mData;
- }
-
- public void setOnListItemListener(OnListItemListener listener) {
- mOnListItemListener = listener;
- }
-
- public OnListItemListener getOnListItemListener() {
- return mOnListItemListener;
- }
-
- public int getSize() {
- return mData == null ? 0 : mData.size();
- }
-
- @Override
- public int getCount() {
- return mData == null || mData.isEmpty() ? 0 : mData.size();
- }
-
- @Override
- public T getItem(int position) {
- return mData != null && checkPosition(position) ? mData.get(position) : null;
- }
-
- private boolean checkPosition(int position) {
- return position >= 0 && position <= mData.size() - 1;
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public abstract View getView(int position, View convertView, ViewGroup parent);
-
- public Context getContext() {
- return mContext;
- }
+
+ private final List mData = new ArrayList<>();
+ private Context mContext;
+ /**
+ * 当前点击的条目
+ */
+ protected int mSelectPosition = -1;
+
+ public XListAdapter(Context context) {
+ mContext = context;
+ }
+
+ public XListAdapter(Context context, List data) {
+ mContext = context;
+ setData(data);
+ }
+
+ public XListAdapter(Context context, T[] data) {
+ mContext = context;
+ setData(data);
+ }
+
+ public void setData(List data) {
+ if (data != null) {
+ mData.clear();
+ mData.addAll(data);
+ mSelectPosition = -1;
+ notifyDataSetChanged();
+ }
+ }
+
+ public void setData(T[] data) {
+ if (data != null && data.length > 0) {
+ setData(Arrays.asList(data));
+ }
+ }
+
+ public void addData(List data) {
+ if (data != null && !data.isEmpty()) {
+ mData.addAll(data);
+ notifyDataSetChanged();
+ }
+ }
+
+ public void addData(T[] data) {
+ addData(Arrays.asList(data));
+ }
+
+ public void addData(T data) {
+ if (data != null) {
+ mData.add(data);
+ notifyDataSetChanged();
+ }
+ }
+
+ public void removeElement(T element) {
+ if (mData.contains(element)) {
+ mData.remove(element);
+ notifyDataSetChanged();
+ }
+ }
+
+ public void removeElement(int position) {
+ if (mData.size() > position) {
+ mData.remove(position);
+ notifyDataSetChanged();
+ }
+ }
+
+ public void removeElements(List elements) {
+ if (elements != null && elements.size() > 0 && mData.size() >= elements.size()) {
+ for (T element : elements) {
+ if (mData.contains(element)) {
+ mData.remove(element);
+ }
+ }
+ notifyDataSetChanged();
+ }
+ }
+
+ public void removeElements(T[] elements) {
+ if (elements != null && elements.length > 0) {
+ removeElements(Arrays.asList(elements));
+ }
+ }
+
+ public void updateElement(T element, int position) {
+ if (checkPosition(position)) {
+ mData.set(position, element);
+ notifyDataSetChanged();
+ }
+ }
+
+ public void addElement(T element) {
+ if (element != null) {
+ mData.add(element);
+ notifyDataSetChanged();
+ }
+ }
+
+ public void clearData() {
+ mData.clear();
+ mSelectPosition = -1;
+ notifyDataSetChanged();
+ }
+
+ public void clearNotNotify() {
+ mData.clear();
+ mSelectPosition = -1;
+ }
+
+ protected void visible(boolean flag, View view) {
+ if (flag) {
+ view.setVisibility(View.VISIBLE);
+ }
+ }
+
+ protected void gone(boolean flag, View view) {
+ if (flag) {
+ view.setVisibility(View.GONE);
+ }
+ }
+
+ protected void inVisible(View view) {
+ view.setVisibility(View.INVISIBLE);
+ }
+
+ protected Drawable getDrawable(int resId) {
+ return mContext.getResources().getDrawable(resId);
+ }
+
+ protected String getString(int resId) {
+ return mContext.getResources().getString(resId);
+ }
+
+ protected int getColor(int resId) {
+ return mContext.getResources().getColor(resId);
+ }
+
+ public List getItems() {
+ return mData;
+ }
+
+ public int getSize() {
+ return mData.size();
+ }
+
+ @Override
+ public int getCount() {
+ return mData.size();
+ }
+
+ @Override
+ public T getItem(int position) {
+ return checkPosition(position) ? mData.get(position) : null;
+ }
+
+ private boolean checkPosition(int position) {
+ return position >= 0 && position <= mData.size() - 1;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public abstract View getView(int position, View convertView, ViewGroup parent);
+
+ public Context getContext() {
+ return mContext;
+ }
+
+ /**
+ * @return 当前列表的选中项
+ */
+ public int getSelectPosition() {
+ return mSelectPosition;
+ }
+
+ /**
+ * 设置当前列表的选中项
+ *
+ * @param selectPosition
+ * @return
+ */
+ public XListAdapter setSelectPosition(int selectPosition) {
+ mSelectPosition = selectPosition;
+ notifyDataSetChanged();
+ return this;
+ }
+
+ /**
+ * 获取当前列表选中项
+ *
+ * @return 当前列表选中项
+ */
+ public T getSelectItem() {
+ return getItem(mSelectPosition);
+ }
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/adapter/recyclerview/BaseRecyclerAdapter.java b/xui_lib/src/main/java/com/xuexiang/xui/adapter/recyclerview/BaseRecyclerAdapter.java
index 881cdef8..f1de33ed 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/adapter/recyclerview/BaseRecyclerAdapter.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/adapter/recyclerview/BaseRecyclerAdapter.java
@@ -21,7 +21,7 @@
import androidx.annotation.NonNull;
-import java.util.List;
+import java.util.Collection;
/**
* 通用的RecyclerView适配器
@@ -35,7 +35,7 @@ public BaseRecyclerAdapter() {
super();
}
- public BaseRecyclerAdapter(List list) {
+ public BaseRecyclerAdapter(Collection list) {
super(list);
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/adapter/recyclerview/XRecyclerAdapter.java b/xui_lib/src/main/java/com/xuexiang/xui/adapter/recyclerview/XRecyclerAdapter.java
index a6307ac7..a46d1678 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/adapter/recyclerview/XRecyclerAdapter.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/adapter/recyclerview/XRecyclerAdapter.java
@@ -54,13 +54,13 @@ public abstract class XRecyclerAdapter ext
/**
* 当前点击的条目
*/
- private int mSelectPosition = -1;
+ protected int mSelectPosition = -1;
public XRecyclerAdapter() {
}
- public XRecyclerAdapter(List list) {
+ public XRecyclerAdapter(Collection list) {
if (list != null) {
mData.addAll(list);
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/AdapterItem.java b/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/AdapterItem.java
index 75347faf..a2a34731 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/AdapterItem.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/AdapterItem.java
@@ -22,6 +22,18 @@ public class AdapterItem {
*/
private Drawable mIcon;
+ public static AdapterItem of(CharSequence title) {
+ return new AdapterItem(title);
+ }
+
+ public static AdapterItem[] arrayof(CharSequence[] title) {
+ AdapterItem[] array = new AdapterItem[title.length];
+ for (int i = 0; i < array.length; i++) {
+ array[i] = new AdapterItem(title[i]);
+ }
+ return array;
+ }
+
public AdapterItem(CharSequence title) {
mTitle = title;
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/ExpandableItem.java b/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/ExpandableItem.java
new file mode 100644
index 00000000..9da057f0
--- /dev/null
+++ b/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/ExpandableItem.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xui.adapter.simple;
+
+import androidx.annotation.NonNull;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 简易的二级适配项
+ *
+ * @author xuexiang
+ * @since 2019-11-11 14:07
+ */
+public class ExpandableItem {
+ /**
+ * 父项
+ */
+ private AdapterItem mGroup;
+ /**
+ * 子项
+ */
+ private List mChild;
+
+ public static ExpandableItem of(@NonNull AdapterItem group) {
+ return new ExpandableItem(group);
+ }
+
+ public ExpandableItem(@NonNull AdapterItem group) {
+ mGroup = group;
+ mChild = new ArrayList<>();
+ }
+
+ public ExpandableItem(@NonNull AdapterItem group, AdapterItem... child) {
+ mGroup = group;
+ mChild = new ArrayList<>(Arrays.asList(child));
+ }
+
+ public ExpandableItem(@NonNull AdapterItem group, @NonNull List child) {
+ mGroup = group;
+ mChild = child;
+ }
+
+ public ExpandableItem addChild(AdapterItem child) {
+ if (mChild == null) {
+ mChild = new ArrayList<>();
+ }
+ mChild.add(child);
+ return this;
+ }
+
+ public ExpandableItem addChild(int index, AdapterItem child) {
+ if (mChild == null) {
+ mChild = new ArrayList<>();
+ }
+ mChild.add(index, child);
+ return this;
+ }
+
+ public ExpandableItem addChild(AdapterItem... child) {
+ if (mChild == null) {
+ mChild = new ArrayList<>();
+ }
+ mChild.addAll(Arrays.asList(child));
+ return this;
+ }
+
+ public AdapterItem getGroup() {
+ return mGroup;
+ }
+
+ public ExpandableItem setGroup(AdapterItem group) {
+ mGroup = group;
+ return this;
+ }
+
+ public List getChild() {
+ return mChild;
+ }
+
+ public int getChildSize() {
+ return mChild != null ? mChild.size() : 0;
+ }
+
+ public AdapterItem getChildItem(int index) {
+ return mChild != null ? mChild.get(index) : null;
+ }
+
+ public ExpandableItem setChild(List child) {
+ mChild = child;
+ return this;
+ }
+}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/XUISimpleAdapter.java b/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/XUISimpleAdapter.java
index 4c149485..55c75627 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/XUISimpleAdapter.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/XUISimpleAdapter.java
@@ -78,6 +78,7 @@ public XUISimpleAdapter setPaddingLeftDp(int paddingLeftDp) {
/**
* 创建简单的适配器【不含图标】
+ *
* @param context
* @param data
* @return
@@ -96,6 +97,7 @@ public static XUISimpleAdapter create(Context context, String[] data) {
/**
* 创建简单的适配器【不含图标】
+ *
* @param context
* @param data
* @return
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/XUISimpleExpandableListAdapter.java b/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/XUISimpleExpandableListAdapter.java
new file mode 100644
index 00000000..4c8d3b9c
--- /dev/null
+++ b/xui_lib/src/main/java/com/xuexiang/xui/adapter/simple/XUISimpleExpandableListAdapter.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xui.adapter.simple;
+
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.appcompat.widget.AppCompatImageView;
+
+import com.xuexiang.xui.R;
+import com.xuexiang.xui.utils.DensityUtils;
+import com.xuexiang.xui.utils.ThemeUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 简易的可伸缩列表适配器
+ *
+ * @author xuexiang
+ * @since 2019-11-11 14:01
+ */
+public class XUISimpleExpandableListAdapter extends BaseExpandableListAdapter {
+ /**
+ * 数据
+ */
+ private List mData;
+
+ private int mPaddingLeftPx;
+
+ private int mArrowUpResId = R.drawable.xui_ic_expand_arrow_up;
+ private int mArrowDownResId = R.drawable.xui_ic_expand_arrow_down;
+
+ public XUISimpleExpandableListAdapter(List data) {
+ mData = data;
+ }
+
+ public XUISimpleExpandableListAdapter(ExpandableItem... data) {
+ mData = new ArrayList<>(Arrays.asList(data));
+ }
+
+ @Override
+ public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
+ GroupViewHolder groupViewHolder;
+ if (convertView == null) {
+ convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.xui_layout_expand_group_item, parent, false);
+ groupViewHolder = new GroupViewHolder();
+ groupViewHolder.ivIcon = convertView.findViewById(R.id.iv_icon);
+ groupViewHolder.tvTitle = convertView.findViewById(R.id.tv_group_name);
+ groupViewHolder.ivIndicator = convertView.findViewById(R.id.iv_indicator);
+ convertView.setTag(groupViewHolder);
+ } else {
+ groupViewHolder = (GroupViewHolder) convertView.getTag();
+ }
+ AdapterItem group = getGroup(groupPosition).getGroup();
+ if (group != null) {
+ groupViewHolder.tvTitle.setText(group.getTitle());
+ groupViewHolder.ivIndicator.setImageResource(isExpanded ? mArrowUpResId : mArrowDownResId);
+ if (group.getIcon() != null) {
+ groupViewHolder.ivIcon.setVisibility(View.VISIBLE);
+ groupViewHolder.ivIcon.setImageDrawable(group.getIcon());
+ } else {
+ groupViewHolder.ivIcon.setVisibility(View.GONE);
+ }
+ }
+ return convertView;
+ }
+
+ @Override
+ public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
+ ChildViewHolder childViewHolder;
+ if (convertView == null) {
+ convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.xui_layout_expand_child_item, parent, false);
+ childViewHolder = new ChildViewHolder();
+ childViewHolder.llContentView = convertView.findViewById(R.id.ll_content);
+ childViewHolder.ivIcon = convertView.findViewById(R.id.iv_icon);
+ childViewHolder.tvTitle = convertView.findViewById(R.id.tv_child_name);
+
+ if (mPaddingLeftPx != 0) {
+ int padding = ThemeUtils.resolveDimension(parent.getContext(), R.attr.xui_config_content_spacing_vertical);
+ childViewHolder.llContentView.setPadding(mPaddingLeftPx, padding, padding, padding);
+ childViewHolder.llContentView.setGravity(Gravity.CENTER_VERTICAL);
+ } else {
+ childViewHolder.llContentView.setGravity(Gravity.CENTER);
+ }
+ convertView.setTag(childViewHolder);
+ } else {
+ childViewHolder = (ChildViewHolder) convertView.getTag();
+ }
+ AdapterItem child = getChild(groupPosition, childPosition);
+ if (child != null) {
+ childViewHolder.tvTitle.setText(child.getTitle());
+ if (child.getIcon() != null) {
+ childViewHolder.ivIcon.setVisibility(View.VISIBLE);
+ childViewHolder.ivIcon.setImageDrawable(child.getIcon());
+ } else {
+ childViewHolder.ivIcon.setVisibility(View.GONE);
+ }
+ }
+ return convertView;
+ }
+
+ @Override
+ public int getGroupCount() {
+ return mData != null ? mData.size() : 0;
+ }
+
+ @Override
+ public int getChildrenCount(int groupPosition) {
+ return mData != null ? mData.get(groupPosition).getChildSize() : 0;
+ }
+
+ @Override
+ public ExpandableItem getGroup(int groupPosition) {
+ return mData != null ? mData.get(groupPosition) : null;
+ }
+
+ @Override
+ public AdapterItem getChild(int groupPosition, int childPosition) {
+ return mData != null ? mData.get(groupPosition).getChildItem(childPosition) : null;
+ }
+
+ @Override
+ public long getGroupId(int groupPosition) {
+ return groupPosition;
+ }
+
+ @Override
+ public long getChildId(int groupPosition, int childPosition) {
+ return childPosition;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ @Override
+ public boolean isChildSelectable(int groupPosition, int childPosition) {
+ return true;
+ }
+
+ public XUISimpleExpandableListAdapter setPaddingLeftPx(int paddingLeftPx) {
+ mPaddingLeftPx = paddingLeftPx;
+ return this;
+ }
+
+ public XUISimpleExpandableListAdapter setPaddingLeftDp(int paddingLeftDp) {
+ mPaddingLeftPx = DensityUtils.dp2px(paddingLeftDp);
+ return this;
+ }
+
+ /**
+ * 设置箭头样式
+ * @param arrowDownResId
+ * @return
+ */
+ public XUISimpleExpandableListAdapter setArrowStyle(int arrowDownResId, int arrowUpResId) {
+ mArrowDownResId = arrowDownResId;
+ mArrowUpResId = arrowUpResId;
+ return this;
+ }
+
+ private static class GroupViewHolder {
+ AppCompatImageView ivIcon;
+ TextView tvTitle;
+ AppCompatImageView ivIndicator;
+ }
+
+ private static class ChildViewHolder {
+ LinearLayout llContentView;
+ AppCompatImageView ivIcon;
+ TextView tvTitle;
+ }
+}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/utils/CountDownButtonHelper.java b/xui_lib/src/main/java/com/xuexiang/xui/utils/CountDownButtonHelper.java
index 15628ba0..6252166b 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/utils/CountDownButtonHelper.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/utils/CountDownButtonHelper.java
@@ -89,6 +89,7 @@ public void onFinish() {
* 开始倒计时
*/
public void start() {
+ initCountDownTimer();
mButton.setEnabled(false);
mCountDownTimer.start();
}
@@ -130,6 +131,16 @@ public interface OnCountDownListener {
public void cancel() {
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
+ mCountDownTimer = null;
}
}
+
+ /**
+ * 资源回收
+ */
+ public void recycle() {
+ cancel();
+ mListener = null;
+ mButton = null;
+ }
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/utils/DeviceUtils.java b/xui_lib/src/main/java/com/xuexiang/xui/utils/DeviceUtils.java
index d903114b..c212e81e 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/utils/DeviceUtils.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/utils/DeviceUtils.java
@@ -5,11 +5,14 @@
import android.app.AppOpsManager;
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.Point;
import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import androidx.annotation.Nullable;
import android.text.TextUtils;
+import android.view.Display;
+import android.view.WindowManager;
import java.io.File;
import java.io.FileInputStream;
@@ -258,7 +261,26 @@ private static String getLowerCaseName(Properties p, Method get, String key) {
} catch (Exception ignored) {
}
}
- if (name != null) name = name.toLowerCase();
+ if (name != null) {
+ name = name.toLowerCase();
+ }
return name;
}
+
+ /**
+ * 获取屏幕尺寸
+ */
+ @SuppressWarnings("deprecation")
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
+ public static Point getScreenSize(Context context){
+ WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ Display display = windowManager.getDefaultDisplay();
+ if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2){
+ return new Point(display.getWidth(), display.getHeight());
+ }else{
+ Point point = new Point();
+ display.getSize(point);
+ return point;
+ }
+ }
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/utils/ResUtils.java b/xui_lib/src/main/java/com/xuexiang/xui/utils/ResUtils.java
index 1e1c8d0b..1edc8b6c 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/utils/ResUtils.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/utils/ResUtils.java
@@ -77,7 +77,7 @@ public static Drawable getDrawable(Context context, @DrawableRes int resId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return context.getDrawable(resId);
}
- return context.getResources().getDrawable(resId);
+ return AppCompatResources.getDrawable(context, resId);
}
/**
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/utils/StatusBarUtils.java b/xui_lib/src/main/java/com/xuexiang/xui/utils/StatusBarUtils.java
index 841bd0d9..fc41e018 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/utils/StatusBarUtils.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/utils/StatusBarUtils.java
@@ -5,9 +5,11 @@
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
+
import androidx.annotation.ColorInt;
import androidx.annotation.IntDef;
import androidx.core.view.ViewCompat;
+
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -61,6 +63,24 @@ private StatusBarUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
+ /**
+ * 设置沉浸式状态栏样式
+ *
+ * @param activity
+ * @param isDark 是否是深色的状态栏
+ * @param colorOn5x 颜色
+ */
+ public static void initStatusBarStyle(Activity activity, boolean isDark, @ColorInt int colorOn5x) {
+ //设置沉浸式状态栏的颜色
+ translucent(activity, colorOn5x);
+ //修改状态栏的字体颜色
+ if (isDark) {
+ setStatusBarDarkMode(activity);
+ } else {
+ setStatusBarLightMode(activity);
+ }
+ }
+
/**
* 沉浸式状态栏。
* 支持 4.4 以上版本的 MIUI 和 Flyme,以及 5.0 以上版本的其他 Android。
@@ -512,7 +532,7 @@ public static void fullScreen(Window window) {
* @param navigationBarColor 导航栏的颜色
*/
public static void cancelFullScreen(Activity activity, @ColorInt int statusBarColor, @ColorInt int navigationBarColor) {
- cancelFullScreen(activity, statusBarColor, navigationBarColor);
+ cancelFullScreen(activity.getWindow(), statusBarColor, navigationBarColor);
}
/**
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/XUIWrapContentExpandableListView.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/XUIWrapContentExpandableListView.java
new file mode 100644
index 00000000..8a88384b
--- /dev/null
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/XUIWrapContentExpandableListView.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xui.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.widget.ExpandableListView;
+
+import com.xuexiang.xui.R;
+
+/**
+ * @author xuexiang
+ * @since 2019-11-11 11:27
+ */
+public class XUIWrapContentExpandableListView extends ExpandableListView {
+
+ private int mMaxHeight = Integer.MAX_VALUE >> 2;
+
+ public XUIWrapContentExpandableListView(Context context) {
+ super(context);
+ }
+
+ public XUIWrapContentExpandableListView(Context context, int maxHeight) {
+ super(context);
+ mMaxHeight = maxHeight;
+ }
+
+ public XUIWrapContentExpandableListView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initAttrs(context, attrs);
+ }
+
+ public XUIWrapContentExpandableListView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initAttrs(context, attrs);
+ }
+
+ /**
+ * 初始化属性
+ *
+ * @param context
+ * @param attrs
+ */
+ private void initAttrs(Context context, AttributeSet attrs) {
+ TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.XUIWrapContentExpandableListView);
+ if (ta != null) {
+ mMaxHeight = ta.getDimensionPixelSize(R.styleable.XUIWrapContentExpandableListView_wcelv_max_height, mMaxHeight);
+ ta.recycle();
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int expandSpec = MeasureSpec.makeMeasureSpec(mMaxHeight, MeasureSpec.AT_MOST);
+ super.onMeasure(widthMeasureSpec, expandSpec);
+ }
+
+ /**
+ * 设置最大高度
+ *
+ * @param maxHeight 最大高度[px]
+ */
+ public void setMaxHeight(int maxHeight) {
+ if (mMaxHeight != maxHeight) {
+ mMaxHeight = maxHeight;
+ requestLayout();
+ }
+ }
+}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/actionbar/TitleBar.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/actionbar/TitleBar.java
index ab1ee364..26d95300 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/actionbar/TitleBar.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/actionbar/TitleBar.java
@@ -596,7 +596,7 @@ public TitleBar setActionTextColor(int colorResId) {
/**
* Function to set a click listener for Title TextView
*
- * @param listener the onClickListener
+ * @param listener the onClick
*/
public TitleBar setOnTitleClickListener(OnClickListener listener) {
mCenterText.setOnClickListener(listener);
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/SimpleImageBanner.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/SimpleImageBanner.java
index 701ec866..747b946b 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/SimpleImageBanner.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/SimpleImageBanner.java
@@ -10,11 +10,12 @@
import android.widget.LinearLayout;
import android.widget.TextView;
-import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.xuexiang.xui.R;
import com.xuexiang.xui.utils.ResUtils;
import com.xuexiang.xui.widget.banner.widget.banner.base.BaseIndicatorBanner;
import com.xuexiang.xui.widget.imageview.ImageLoader;
+import com.xuexiang.xui.widget.imageview.strategy.DiskCacheStrategyEnum;
+import com.xuexiang.xui.widget.imageview.strategy.LoadOption;
import java.lang.ref.WeakReference;
@@ -103,9 +104,10 @@ protected void loadingImageView(ImageView iv, BannerItem item) {
String imgUrl = item.imgUrl;
if (!TextUtils.isEmpty(imgUrl)) {
- ImageLoader.get().loadImage(iv, imgUrl,
- itemWidth, itemHeight, mColorDrawable,
- mEnableCache ? DiskCacheStrategy.RESOURCE : DiskCacheStrategy.NONE);
+ LoadOption option = LoadOption.of(mColorDrawable)
+ .setCacheStrategy(mEnableCache ? DiskCacheStrategyEnum.RESOURCE : DiskCacheStrategyEnum.NONE)
+ .setSize(itemWidth, itemHeight);
+ ImageLoader.get().loadImage(iv, imgUrl, option);
} else {
iv.setImageDrawable(mColorDrawable);
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/base/BaseBanner.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/base/BaseBanner.java
index c30d6b72..38baf095 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/base/BaseBanner.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/base/BaseBanner.java
@@ -6,10 +6,6 @@
import android.graphics.Typeface;
import android.os.Handler;
import android.os.Message;
-
-import androidx.viewpager.widget.PagerAdapter;
-import androidx.viewpager.widget.ViewPager;
-import androidx.viewpager.widget.ViewPager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -23,6 +19,9 @@
import android.widget.RelativeLayout;
import android.widget.TextView;
+import androidx.viewpager.widget.PagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+
import com.xuexiang.xui.R;
import com.xuexiang.xui.logs.UILog;
import com.xuexiang.xui.widget.banner.widget.loopviewpager.FixedSpeedScroller;
@@ -600,18 +599,6 @@ public boolean dispatchTouchEvent(MotionEvent ev) {
return super.dispatchTouchEvent(ev);
}
-// @Override
-// protected void onWindowVisibilityChanged(int visibility) {
-// super.onWindowVisibilityChanged(visibility);
-// if (mIsSmart) {
-// if (visibility != VISIBLE) {
-// pauseScroll();
-// } else {
-// goOnScroll();
-// }
-// }
-// }
-
private class InnerBannerAdapter extends PagerAdapter {
@Override
public int getCount() {
@@ -624,8 +611,8 @@ public Object instantiateItem(ViewGroup container, final int position) {
inflate.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- if (mOnItemClickL != null) {
- mOnItemClickL.onItemClick(position);
+ if (mOnItemClickListener != null) {
+ mOnItemClickListener.onItemClick(v, getItem(position), position);
}
}
});
@@ -705,15 +692,31 @@ public BaseBanner addOnPageChangeListener(ViewPager.OnPageChangeListener listene
return this;
}
- private OnItemClickL mOnItemClickL;
+ private OnItemClickListener mOnItemClickListener;
- public BaseBanner setOnItemClickL(OnItemClickL onItemClickL) {
- this.mOnItemClickL = onItemClickL;
+ /**
+ * 设置条目点击监听
+ *
+ * @param onItemClickListener
+ * @return
+ */
+ public BaseBanner setOnItemClickListener(OnItemClickListener onItemClickListener) {
+ mOnItemClickListener = onItemClickListener;
return this;
}
- public interface OnItemClickL {
- void onItemClick(int position);
+ /**
+ * 条目点击监听
+ *
+ * @param
+ */
+ public interface OnItemClickListener {
+ /**
+ * @param view
+ * @param item
+ * @param position
+ */
+ void onItemClick(View view, E item, int position);
}
/**
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/base/BaseImageBanner.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/base/BaseImageBanner.java
index a2cc99b4..8fcb7b2a 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/base/BaseImageBanner.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/banner/widget/banner/base/BaseImageBanner.java
@@ -27,11 +27,12 @@
import android.widget.LinearLayout;
import android.widget.TextView;
-import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.xuexiang.xui.R;
import com.xuexiang.xui.utils.ResUtils;
import com.xuexiang.xui.widget.banner.widget.banner.BannerItem;
import com.xuexiang.xui.widget.imageview.ImageLoader;
+import com.xuexiang.xui.widget.imageview.strategy.DiskCacheStrategyEnum;
+import com.xuexiang.xui.widget.imageview.strategy.LoadOption;
import java.lang.ref.WeakReference;
@@ -134,11 +135,12 @@ protected void loadingImageView(ImageView iv, BannerItem item) {
iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
iv.setLayoutParams(new LinearLayout.LayoutParams(itemWidth, itemHeight));
- ImageLoader.get().loadImage(iv, imgUrl,
- itemWidth, itemHeight, mPlaceHolder,
- mEnableCache ? DiskCacheStrategy.RESOURCE : DiskCacheStrategy.NONE);
+ LoadOption option = LoadOption.of(mPlaceHolder)
+ .setSize(itemWidth, itemHeight)
+ .setCacheStrategy(mEnableCache ? DiskCacheStrategyEnum.RESOURCE : DiskCacheStrategyEnum.NONE);
+ ImageLoader.get().loadImage(iv, imgUrl, option);
} else {
- ImageLoader.get().loadImage(iv, imgUrl, mPlaceHolder, mEnableCache ? DiskCacheStrategy.RESOURCE : DiskCacheStrategy.NONE);
+ ImageLoader.get().loadImage(iv, imgUrl, mPlaceHolder, mEnableCache ? DiskCacheStrategyEnum.RESOURCE : DiskCacheStrategyEnum.NONE);
}
} else {
iv.setImageDrawable(mPlaceHolder);
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/DialogInit.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/DialogInit.java
index 832e9365..e01ca836 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/DialogInit.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/DialogInit.java
@@ -80,28 +80,28 @@ static int getTheme(@NonNull MaterialDialog.Builder builder) {
@LayoutRes
static int getInflateLayout(MaterialDialog.Builder builder) {
if (builder.customView != null) {
- return R.layout.md_dialog_custom;
+ return R.layout.md_layout_dialog_custom;
} else if (builder.items != null || builder.adapter != null) {
if (builder.checkBoxPrompt != null) {
- return R.layout.md_dialog_list_check;
+ return R.layout.md_layout_dialog_list_check;
}
- return R.layout.md_dialog_list;
+ return R.layout.md_layout_dialog_list;
} else if (builder.progress > -2) {
- return R.layout.md_dialog_progress;
+ return R.layout.md_layout_dialog_progress;
} else if (builder.indeterminateProgress) {
if (builder.indeterminateIsHorizontalProgress) {
- return R.layout.md_dialog_progress_indeterminate_horizontal;
+ return R.layout.md_layout_dialog_progress_indeterminate_horizontal;
}
- return R.layout.md_dialog_progress_indeterminate;
+ return R.layout.md_layout_dialog_progress_indeterminate;
} else if (builder.inputCallback != null) {
if (builder.checkBoxPrompt != null) {
- return R.layout.md_dialog_input_check;
+ return R.layout.md_layout_dialog_input_check;
}
- return R.layout.md_dialog_input;
+ return R.layout.md_layout_dialog_input;
} else if (builder.checkBoxPrompt != null) {
- return R.layout.md_dialog_basic_check;
+ return R.layout.md_layout_dialog_basic_check;
} else {
- return R.layout.md_dialog_basic;
+ return R.layout.md_layout_dialog_basic;
}
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/MaterialDialog.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/MaterialDialog.java
index b4cd6fc4..345a8766 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/MaterialDialog.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/MaterialDialog.java
@@ -1035,11 +1035,11 @@ enum ListType {
public static int getLayoutForType(ListType type) {
switch (type) {
case REGULAR:
- return R.layout.md_listitem;
+ return R.layout.md_layout_listitem;
case SINGLE:
- return R.layout.md_listitem_singlechoice;
+ return R.layout.md_layout_listitem_singlechoice;
case MULTI:
- return R.layout.md_listitem_multichoice;
+ return R.layout.md_layout_listitem_multichoice;
default:
throw new IllegalArgumentException("Not a valid list type");
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/internal/MDRootLayout.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/internal/MDRootLayout.java
index b31f6e83..0d8e5246 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/internal/MDRootLayout.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/internal/MDRootLayout.java
@@ -42,7 +42,7 @@
/**
* @author Kevin Barry (teslacoil) 4/02/2015 This is the top level view for all MaterialDialogs It
- * handles the layout of: titleFrame (md_stub_titleframe) content (text, custom view, listview,
+ * handles the layout of: titleFrame (md_layout_stub_titleframe) content (text, custom view, listview,
* etc) buttonDefault... (either stacked or horizontal)
*/
public class MDRootLayout extends ViewGroup {
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/simplelist/MaterialSimpleListAdapter.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/simplelist/MaterialSimpleListAdapter.java
index 2b4db4de..ea809f5e 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/simplelist/MaterialSimpleListAdapter.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/materialdialog/simplelist/MaterialSimpleListAdapter.java
@@ -91,7 +91,7 @@ public MaterialDialog getMaterialDialog() {
public SimpleListVH onCreateViewHolder(ViewGroup parent, int viewType) {
final View view =
LayoutInflater.from(parent.getContext())
- .inflate(R.layout.md_simplelist_item, parent, false);
+ .inflate(R.layout.md_layout_simplelist_item, parent, false);
return new SimpleListVH(view, this);
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/edittext/MultiLineEditText.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/edittext/MultiLineEditText.java
index d80402d9..8f4f06e5 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/edittext/MultiLineEditText.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/edittext/MultiLineEditText.java
@@ -230,11 +230,7 @@ private long calculateLength(CharSequence c) {
}
private int calculateLengthIgnoreCnOrEn(CharSequence c) {
- int len = 0;
- for (int i = 0; i < c.length(); i++) {
- len++;
- }
- return len;
+ return c != null ? c.length() : 0;
}
private void configCount() {
@@ -249,13 +245,12 @@ private void configCount() {
private void updateCount(int nowCount) {
if (mIsShowSurplusNumber) {
- mTvInputNumber.setText(String.valueOf((mMaxCount - nowCount)) + "/" + mMaxCount);
+ mTvInputNumber.setText((mMaxCount - nowCount) + "/" + mMaxCount);
} else {
- mTvInputNumber.setText(String.valueOf(nowCount) + "/" + mMaxCount);
+ mTvInputNumber.setText(nowCount + "/" + mMaxCount);
}
}
-
public EditText getEditText() {
return mEtInput;
}
@@ -264,7 +259,15 @@ public TextView getCountTextView() {
return mTvInputNumber;
}
+ /**
+ * 设置填充内容
+ *
+ * @param content
+ */
public void setContentText(String content) {
+ if (content != null && calculateContentLength(content) > mMaxCount) {
+ content = content.substring(0, getSubStringIndex(content));
+ }
mContentText = content;
if (mEtInput == null) {
return;
@@ -272,6 +275,28 @@ public void setContentText(String content) {
mEtInput.setText(mContentText);
}
+ private long calculateContentLength(String content) {
+ return mIgnoreCnOrEn ? calculateLengthIgnoreCnOrEn(content) : calculateLength(content);
+ }
+
+ private int getSubStringIndex(String content) {
+ if (!mIgnoreCnOrEn) {
+ double len = 0;
+ for (int i = 0; i < content.length(); i++) {
+ int tmp = (int) content.charAt(i);
+ if (tmp > 0 && tmp < 127) {
+ len += 0.5;
+ } else {
+ len++;
+ }
+ if (Math.round(len) == mMaxCount) {
+ return i + 1;
+ }
+ }
+ }
+ return mMaxCount;
+ }
+
/**
* 获取输入的内容
*
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/flowlayout/BaseTagAdapter.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/flowlayout/BaseTagAdapter.java
index 4274bb94..873eba0d 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/flowlayout/BaseTagAdapter.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/flowlayout/BaseTagAdapter.java
@@ -19,7 +19,6 @@ public abstract class BaseTagAdapter extends BaseListAdapter impleme
* 初始化选中的位置
*/
private List mPositions = new ArrayList<>();
-
/**
* 当前选中的索引集合
*/
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/flowlayout/FlowTagLayout.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/flowlayout/FlowTagLayout.java
index ff7a5a80..bfe934df 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/flowlayout/FlowTagLayout.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/flowlayout/FlowTagLayout.java
@@ -391,7 +391,7 @@ public void onClick(View v) {
//更新点击状态
mCheckedTagArray.put(index, false);
childView.setSelected(false);
- setSelectedIndexs(null);
+ setSelectedIndexs(new ArrayList());
if (mOnTagSelectListener != null) {
mOnTagSelectListener.onItemSelect(FlowTagLayout.this, index, new ArrayList());
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/guidview/GuideCaseView.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/guidview/GuideCaseView.java
index 154a428e..0f00673f 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/guidview/GuideCaseView.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/guidview/GuideCaseView.java
@@ -391,7 +391,6 @@ public void hide() {
public void onAnimationStart(Animation animation) {
}
-
@Override
public void onAnimationEnd(Animation animation) {
removeView();
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/ImageLoader.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/ImageLoader.java
index 139e5024..d598cac0 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/ImageLoader.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/ImageLoader.java
@@ -23,8 +23,10 @@
import androidx.annotation.NonNull;
-import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.xuexiang.xui.widget.imageview.strategy.DiskCacheStrategyEnum;
import com.xuexiang.xui.widget.imageview.strategy.IImageLoadStrategy;
+import com.xuexiang.xui.widget.imageview.strategy.ILoadListener;
+import com.xuexiang.xui.widget.imageview.strategy.LoadOption;
import com.xuexiang.xui.widget.imageview.strategy.impl.GlideImageLoadStrategy;
/**
@@ -78,40 +80,162 @@ public static ImageLoader get() {
return sInstance;
}
-
@Override
public void loadImage(@NonNull ImageView imageView, Object path) {
mStrategy.loadImage(imageView, path);
}
+ /**
+ * 加载图片【最常用】
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param listener 加载监听
+ */
+ @Override
+ public void loadImage(@NonNull ImageView imageView, Object path, @NonNull ILoadListener listener) {
+ mStrategy.loadImage(imageView, path, listener);
+ }
+
@Override
public void loadGifImage(@NonNull ImageView imageView, Object path) {
mStrategy.loadGifImage(imageView, path);
}
+ /**
+ * 加载图片【最常用】
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param listener 加载监听
+ */
@Override
- public void loadImage(@NonNull ImageView imageView, Object path, DiskCacheStrategy strategy) {
+ public void loadGifImage(@NonNull ImageView imageView, Object path, @NonNull ILoadListener listener) {
+ mStrategy.loadGifImage(imageView, path, listener);
+ }
+
+ @Override
+ public void loadImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy) {
mStrategy.loadImage(imageView, path, strategy);
}
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param strategy 磁盘缓存策略
+ * @param listener 加载监听
+ */
+ @Override
+ public void loadImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy, ILoadListener listener) {
+ mStrategy.loadImage(imageView, path, strategy, listener);
+ }
+
@Override
- public void loadGifImage(@NonNull ImageView imageView, Object path, DiskCacheStrategy strategy) {
+ public void loadGifImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy) {
mStrategy.loadGifImage(imageView, path, strategy);
}
+ /**
+ * 加载Gif图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param strategy 磁盘缓存策略
+ * @param listener 加载监听
+ */
+ @Override
+ public void loadGifImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy, ILoadListener listener) {
+ mStrategy.loadGifImage(imageView, path, strategy, listener);
+ }
+
@Override
- public void loadImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategy strategy) {
+ public void loadImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy) {
mStrategy.loadImage(imageView, path, placeholder, strategy);
}
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param placeholder 占位图片
+ * @param strategy 磁盘缓存策略
+ * @param listener 加载监听
+ */
+ @Override
+ public void loadImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy, ILoadListener listener) {
+ mStrategy.loadImage(imageView, path, placeholder, strategy, listener);
+ }
+
@Override
- public void loadGifImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategy strategy) {
+ public void loadGifImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy) {
mStrategy.loadGifImage(imageView, path, placeholder, strategy);
}
+ /**
+ * 加载Gif图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param placeholder 占位图片
+ * @param strategy 磁盘缓存策略
+ * @param listener 加载监听
+ */
+ @Override
+ public void loadGifImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy, ILoadListener listener) {
+ mStrategy.loadGifImage(imageView, path, placeholder, strategy, listener);
+ }
+
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ */
+ @Override
+ public void loadImage(@NonNull ImageView imageView, Object path, LoadOption loadOption) {
+ mStrategy.loadImage(imageView, path, loadOption);
+ }
+
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ * @param listener 加载监听
+ */
+ @Override
+ public void loadImage(@NonNull ImageView imageView, Object path, LoadOption loadOption, ILoadListener listener) {
+ mStrategy.loadImage(imageView, path, loadOption, listener);
+ }
+
+ /**
+ * 加载Gif图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ */
+ @Override
+ public void loadGifImage(@NonNull ImageView imageView, Object path, LoadOption loadOption) {
+ mStrategy.loadGifImage(imageView, path, loadOption);
+ }
+
+ /**
+ * 加载Gif图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ * @param listener 加载监听
+ */
@Override
- public void loadImage(@NonNull ImageView imageView, Object path, int width, int height, Drawable placeholder, DiskCacheStrategy strategy) {
- mStrategy.loadImage(imageView, path, width, height, placeholder, strategy);
+ public void loadGifImage(@NonNull ImageView imageView, Object path, LoadOption loadOption, ILoadListener listener) {
+ mStrategy.loadGifImage(imageView, path, loadOption, listener);
}
@Override
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/edit/PhotoEditor.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/edit/PhotoEditor.java
index 6235f69a..9076722b 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/edit/PhotoEditor.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/edit/PhotoEditor.java
@@ -339,7 +339,7 @@ private View getLayout(final ViewType viewType) {
View rootView = null;
switch (viewType) {
case TEXT:
- rootView = mLayoutInflater.inflate(R.layout.layout_photo_editor_text, null);
+ rootView = mLayoutInflater.inflate(R.layout.xui_layout_photo_editor_text, null);
TextView txtText = rootView.findViewById(R.id.tv_editor_text);
if (txtText != null && mDefaultTextTypeface != null) {
txtText.setGravity(Gravity.CENTER);
@@ -349,10 +349,10 @@ private View getLayout(final ViewType viewType) {
}
break;
case IMAGE:
- rootView = mLayoutInflater.inflate(R.layout.layout_photo_editor_image, null);
+ rootView = mLayoutInflater.inflate(R.layout.xui_layout_photo_editor_image, null);
break;
case EMOJI:
- rootView = mLayoutInflater.inflate(R.layout.layout_photo_editor_text, null);
+ rootView = mLayoutInflater.inflate(R.layout.xui_layout_photo_editor_text, null);
TextView txtTextEmoji = rootView.findViewById(R.id.tv_editor_text);
if (txtTextEmoji != null) {
if (mDefaultEmojiTypeface != null) {
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/DiskCacheStrategyEnum.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/DiskCacheStrategyEnum.java
new file mode 100644
index 00000000..d3e4e5f5
--- /dev/null
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/DiskCacheStrategyEnum.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xui.widget.imageview.strategy;
+
+/**
+ * 磁盘缓存策略枚举
+ *
+ * @author xuexiang
+ * @since 2019-11-09 10:58
+ */
+public enum DiskCacheStrategyEnum {
+ /**
+ * Caches remote data with both {@link #DATA} and {@link #RESOURCE}, and local data with
+ * {@link #RESOURCE} only.
+ */
+ ALL,
+ /**
+ * Saves no data to cache.
+ */
+ NONE,
+ /**
+ * Writes retrieved data directly to the disk cache before it's decoded.
+ */
+ DATA,
+ /**
+ * Writes resources to disk after they've been decoded.
+ */
+ RESOURCE,
+ /**
+ * Tries to intelligently choose a strategy
+ */
+ AUTOMATIC,
+}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/IImageLoadStrategy.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/IImageLoadStrategy.java
index 8a4ed11c..a7583638 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/IImageLoadStrategy.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/IImageLoadStrategy.java
@@ -23,8 +23,6 @@
import androidx.annotation.NonNull;
-import com.bumptech.glide.load.engine.DiskCacheStrategy;
-
/**
* 图片加载策略
*
@@ -41,6 +39,15 @@ public interface IImageLoadStrategy {
*/
void loadImage(@NonNull ImageView imageView, Object path);
+ /**
+ * 加载图片【最常用】
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param listener 加载监听
+ */
+ void loadImage(@NonNull ImageView imageView, Object path, @NonNull ILoadListener listener);
+
/**
* 加载Gif图片【最常用】
*
@@ -49,6 +56,17 @@ public interface IImageLoadStrategy {
*/
void loadGifImage(@NonNull ImageView imageView, Object path);
+ /**
+ * 加载图片【最常用】
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param listener 加载监听
+ */
+ void loadGifImage(@NonNull ImageView imageView, Object path, @NonNull ILoadListener listener);
+
+ //=============================================//
+
/**
* 加载图片
*
@@ -56,17 +74,49 @@ public interface IImageLoadStrategy {
* @param path 图片资源的索引
* @param strategy 磁盘缓存策略
*/
- void loadImage(@NonNull ImageView imageView, Object path, DiskCacheStrategy strategy);
+ void loadImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy);
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param strategy 磁盘缓存策略
+ * @param listener 加载监听
+ */
+ void loadImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy, ILoadListener listener);
+
+ /**
+ * 加载Gif图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param strategy 磁盘缓存策略
+ */
+ void loadGifImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy);
+
/**
* 加载Gif图片
*
* @param imageView 图片控件
* @param path 图片资源的索引
* @param strategy 磁盘缓存策略
+ * @param listener 加载监听
*/
- void loadGifImage(@NonNull ImageView imageView, Object path, DiskCacheStrategy strategy);
+ void loadGifImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy, ILoadListener listener);
+
+ //=============================================//
+
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param placeholder 占位图片
+ * @param strategy 磁盘缓存策略
+ */
+ void loadImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy);
/**
* 加载图片
@@ -75,8 +125,9 @@ public interface IImageLoadStrategy {
* @param path 图片资源的索引
* @param placeholder 占位图片
* @param strategy 磁盘缓存策略
+ * @param listener 加载监听
*/
- void loadImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategy strategy);
+ void loadImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy, ILoadListener listener);
/**
* 加载Gif图片
@@ -86,20 +137,60 @@ public interface IImageLoadStrategy {
* @param placeholder 占位图片
* @param strategy 磁盘缓存策略
*/
- void loadGifImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategy strategy);
+ void loadGifImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy);
/**
- * 加载指定宽高的图片
+ * 加载Gif图片
*
* @param imageView 图片控件
* @param path 图片资源的索引
- * @param width 宽
- * @param height 高
* @param placeholder 占位图片
* @param strategy 磁盘缓存策略
+ * @param listener 加载监听
+ */
+ void loadGifImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy, ILoadListener listener);
+
+ //=============================================//
+
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ */
+ void loadImage(@NonNull ImageView imageView, Object path, LoadOption loadOption);
+
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ * @param listener 加载监听
+ */
+ void loadImage(@NonNull ImageView imageView, Object path, LoadOption loadOption, ILoadListener listener);
+
+ /**
+ * 加载Gif图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ */
+ void loadGifImage(@NonNull ImageView imageView, Object path, LoadOption loadOption);
+
+ /**
+ * 加载Gif图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ * @param listener 加载监听
*/
- void loadImage(@NonNull ImageView imageView, Object path, int width, int height, Drawable placeholder, DiskCacheStrategy strategy);
+ void loadGifImage(@NonNull ImageView imageView, Object path, LoadOption loadOption, ILoadListener listener);
+ //=============================================//
/**
* 清除缓存【内存和磁盘缓存】
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/adapter/listview/OnListItemListener.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/ILoadListener.java
old mode 100755
new mode 100644
similarity index 62%
rename from xui_lib/src/main/java/com/xuexiang/xui/adapter/listview/OnListItemListener.java
rename to xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/ILoadListener.java
index eb31a8fd..b0acab6d
--- a/xui_lib/src/main/java/com/xuexiang/xui/adapter/listview/OnListItemListener.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/ILoadListener.java
@@ -15,29 +15,30 @@
*
*/
-package com.xuexiang.xui.adapter.listview;
+package com.xuexiang.xui.widget.imageview.strategy;
+
+import android.graphics.drawable.Drawable;
+
+import androidx.annotation.Nullable;
/**
- * 集合条目监听
- * @author XUE
+ * 加载监听
*
- * @param
+ * @author xuexiang
+ * @since 2019-11-09 10:39
*/
-public interface OnListItemListener {
+public interface ILoadListener {
/**
- * 点击
- * @param position
- * @param model
- * @param tag
+ * 加载成功
*/
- void onItemClick(int position, T model, int tag);
+ void onLoadSuccess();
/**
- * 长按
- * @param position
- * @param model
- * @param tag
+ * 加载失败
+ *
+ * @param error
*/
- void onItemLongClick(int position, T model, int tag);
+ void onLoadFailed(Throwable error);
+
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/LoadOption.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/LoadOption.java
new file mode 100644
index 00000000..28636772
--- /dev/null
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/LoadOption.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xui.widget.imageview.strategy;
+
+import android.graphics.drawable.Drawable;
+
+/**
+ * 加载选项
+ *
+ * @author xuexiang
+ * @since 2019-11-09 11:12
+ */
+public class LoadOption {
+ /**
+ * 磁盘缓存策略
+ */
+ public DiskCacheStrategyEnum cacheStrategy;
+ /**
+ * 占位图
+ */
+ public Drawable placeholder;
+ /**
+ * 宽度
+ */
+ public int width;
+ /**
+ * 高度
+ */
+ public int height;
+
+ public static LoadOption of(DiskCacheStrategyEnum cacheStrategy) {
+ return new LoadOption(cacheStrategy);
+ }
+
+ public static LoadOption of(Drawable placeholder) {
+ return new LoadOption(placeholder);
+ }
+
+ public LoadOption() {
+ }
+
+ public LoadOption(DiskCacheStrategyEnum cacheStrategy) {
+ this.cacheStrategy = cacheStrategy;
+ }
+
+ public LoadOption(Drawable placeholder) {
+ this.placeholder = placeholder;
+ }
+
+ public DiskCacheStrategyEnum getCacheStrategy() {
+ return cacheStrategy;
+ }
+
+ public LoadOption setCacheStrategy(DiskCacheStrategyEnum cacheStrategy) {
+ this.cacheStrategy = cacheStrategy;
+ return this;
+ }
+
+ public Drawable getPlaceholder() {
+ return placeholder;
+ }
+
+ public LoadOption setPlaceholder(Drawable placeholder) {
+ this.placeholder = placeholder;
+ return this;
+ }
+
+ /**
+ * 设置加载图片的宽高
+ *
+ * @param width 宽
+ * @param height 高
+ * @return
+ */
+ public LoadOption setSize(int width, int height) {
+ this.width = width;
+ this.height = height;
+ return this;
+ }
+
+ public boolean hasSize() {
+ return width != 0 && height != 0;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ @Override
+ public String toString() {
+ return "LoadOption{" +
+ "cacheStrategy=" + cacheStrategy +
+ ", placeholder=" + placeholder +
+ ", width=" + width +
+ ", height=" + height +
+ '}';
+ }
+}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/impl/GlideImageLoadStrategy.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/impl/GlideImageLoadStrategy.java
index e361064b..ae65a156 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/impl/GlideImageLoadStrategy.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/imageview/strategy/impl/GlideImageLoadStrategy.java
@@ -17,16 +17,27 @@
package com.xuexiang.xui.widget.imageview.strategy.impl;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
+import com.bumptech.glide.RequestBuilder;
+import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.bumptech.glide.load.engine.GlideException;
+import com.bumptech.glide.load.resource.gif.GifDrawable;
+import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
+import com.bumptech.glide.request.target.Target;
+import com.xuexiang.xui.widget.imageview.strategy.DiskCacheStrategyEnum;
import com.xuexiang.xui.widget.imageview.strategy.IImageLoadStrategy;
+import com.xuexiang.xui.widget.imageview.strategy.ILoadListener;
+import com.xuexiang.xui.widget.imageview.strategy.LoadOption;
/**
* Glide图片加载策略
@@ -43,73 +54,240 @@ public void loadImage(@NonNull ImageView imageView, Object path) {
.into(imageView);
}
+ /**
+ * 加载图片【最常用】
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param listener 加载监听
+ */
@Override
- public void loadGifImage(@NonNull ImageView imageView, Object path) {
+ public void loadImage(@NonNull ImageView imageView, Object path, final @NonNull ILoadListener listener) {
Glide.with(imageView.getContext())
- .asGif()
.load(path)
+ .listener(new RequestListener() {
+ @Override
+ public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
+ listener.onLoadFailed(e);
+ return false;
+ }
+ @Override
+ public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
+ listener.onLoadSuccess();
+ return false;
+ }
+ })
.into(imageView);
}
@Override
- public void loadImage(@NonNull ImageView imageView, Object path, DiskCacheStrategy strategy) {
- RequestOptions options = new RequestOptions()
- .centerCrop()
- .diskCacheStrategy(strategy);
+ public void loadGifImage(@NonNull ImageView imageView, Object path) {
Glide.with(imageView.getContext())
+ .asGif()
.load(path)
- .apply(options)
.into(imageView);
}
+ /**
+ * 加载图片【最常用】
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param listener 加载监听
+ */
@Override
- public void loadGifImage(@NonNull ImageView imageView, Object path, DiskCacheStrategy strategy) {
- RequestOptions options = new RequestOptions()
- .centerCrop()
- .diskCacheStrategy(strategy);
+ public void loadGifImage(@NonNull ImageView imageView, Object path, final @NonNull ILoadListener listener) {
Glide.with(imageView.getContext())
.asGif()
.load(path)
- .apply(options)
+ .listener(new RequestListener() {
+ @Override
+ public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
+ listener.onLoadFailed(e);
+ return false;
+ }
+
+ @Override
+ public boolean onResourceReady(GifDrawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
+ listener.onLoadSuccess();
+ return false;
+ }
+ })
.into(imageView);
}
@Override
- public void loadImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategy strategy) {
- RequestOptions options = new RequestOptions()
- .centerCrop()
- .placeholder(placeholder)
- .diskCacheStrategy(strategy);
- Glide.with(imageView.getContext())
- .load(path)
- .apply(options)
- .into(imageView);
+ public void loadImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy) {
+ loadImage(imageView, path, LoadOption.of(strategy));
}
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param strategy 磁盘缓存策略
+ * @param listener 加载监听
+ */
@Override
- public void loadGifImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategy strategy) {
- RequestOptions options = new RequestOptions()
- .centerCrop()
- .placeholder(placeholder)
- .diskCacheStrategy(strategy);
- Glide.with(imageView.getContext())
- .asGif()
+ public void loadImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy, ILoadListener listener) {
+ loadImage(imageView, path, LoadOption.of(strategy), listener);
+ }
+
+ @Override
+ public void loadGifImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy) {
+ loadGifImage(imageView, path, LoadOption.of(strategy));
+ }
+
+ /**
+ * 加载Gif图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param strategy 磁盘缓存策略
+ * @param listener 加载监听
+ */
+ @Override
+ public void loadGifImage(@NonNull ImageView imageView, Object path, DiskCacheStrategyEnum strategy, ILoadListener listener) {
+ loadGifImage(imageView, path, LoadOption.of(strategy), listener);
+ }
+
+ @Override
+ public void loadImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy) {
+ loadImage(imageView, path, LoadOption.of(placeholder).setCacheStrategy(strategy));
+ }
+
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param placeholder 占位图片
+ * @param strategy 磁盘缓存策略
+ * @param listener 加载监听
+ */
+ @Override
+ public void loadImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy, ILoadListener listener) {
+ loadImage(imageView, path, LoadOption.of(placeholder).setCacheStrategy(strategy), listener);
+ }
+
+ @Override
+ public void loadGifImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy) {
+ loadGifImage(imageView, path, LoadOption.of(placeholder).setCacheStrategy(strategy));
+ }
+
+ /**
+ * 加载Gif图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param placeholder 占位图片
+ * @param strategy 磁盘缓存策略
+ * @param listener 加载监听
+ */
+ @Override
+ public void loadGifImage(@NonNull ImageView imageView, Object path, Drawable placeholder, DiskCacheStrategyEnum strategy, ILoadListener listener) {
+ loadGifImage(imageView, path, LoadOption.of(placeholder).setCacheStrategy(strategy), listener);
+ }
+
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ */
+ @Override
+ public void loadImage(@NonNull ImageView imageView, Object path, LoadOption loadOption) {
+ loadImage(imageView, path, loadOption, null);
+ }
+
+ /**
+ * 加载Gif图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ */
+ @Override
+ public void loadGifImage(@NonNull ImageView imageView, Object path, LoadOption loadOption) {
+ loadGifImage(imageView, path, loadOption, null);
+ }
+
+ /**
+ * 加载图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ */
+ @SuppressLint("CheckResult")
+ @Override
+ public void loadImage(@NonNull ImageView imageView, Object path, LoadOption loadOption, final ILoadListener listener) {
+ RequestBuilder builder = Glide.with(imageView.getContext())
.load(path)
- .apply(options)
- .into(imageView);
+ .apply(getRequestOptions(loadOption));
+ if (listener != null) {
+ builder.listener(new RequestListener() {
+ @Override
+ public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
+ listener.onLoadFailed(e);
+ return false;
+ }
+ @Override
+ public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
+ listener.onLoadSuccess();
+ return false;
+ }
+ });
+ }
+ builder.into(imageView);
}
+ /**
+ * 加载Gif图片
+ *
+ * @param imageView 图片控件
+ * @param path 图片资源的索引
+ * @param loadOption 加载选项
+ */
+ @SuppressLint("CheckResult")
@Override
- public void loadImage(@NonNull ImageView imageView, Object path, int width, int height, Drawable placeholder, DiskCacheStrategy strategy) {
- RequestOptions options = new RequestOptions()
- .centerCrop()
- .override(width, height)
- .placeholder(placeholder)
- .diskCacheStrategy(strategy);
- Glide.with(imageView.getContext())
+ public void loadGifImage(@NonNull ImageView imageView, Object path, LoadOption loadOption, final ILoadListener listener) {
+ RequestBuilder builder = Glide.with(imageView.getContext())
+ .asGif()
.load(path)
- .apply(options)
- .into(imageView);
+ .apply(getRequestOptions(loadOption));
+ if (listener != null) {
+ builder.listener(new RequestListener() {
+ @Override
+ public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
+ listener.onLoadFailed(e);
+ return false;
+ }
+ @Override
+ public boolean onResourceReady(GifDrawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
+ listener.onLoadSuccess();
+ return false;
+ }
+ });
+ }
+ builder.into(imageView);
+ }
+
+ @SuppressLint("CheckResult")
+ private RequestOptions getRequestOptions(LoadOption loadOption) {
+ RequestOptions options = new RequestOptions();
+ if (loadOption.hasSize()) {
+ options.override(loadOption.getWidth(), loadOption.getHeight());
+ }
+ if (loadOption.placeholder != null) {
+ options.placeholder(loadOption.placeholder);
+ }
+ if (loadOption.cacheStrategy != null) {
+ options.diskCacheStrategy(toGlideStrategy(loadOption.cacheStrategy));
+ }
+ return options;
}
@Override
@@ -121,12 +299,33 @@ public void clearCache(Context context) {
@Override
public void clearMemoryCache(Context context) {
Glide.get(context).clearMemory();
-
}
@Override
public void clearDiskCache(Context context) {
Glide.get(context).clearDiskCache();
+ }
+ /**
+ * 策略切换
+ *
+ * @param strategyEnum
+ * @return
+ */
+ private DiskCacheStrategy toGlideStrategy(DiskCacheStrategyEnum strategyEnum) {
+ switch (strategyEnum) {
+ case ALL:
+ return DiskCacheStrategy.ALL;
+ case NONE:
+ return DiskCacheStrategy.NONE;
+ case DATA:
+ return DiskCacheStrategy.DATA;
+ case RESOURCE:
+ return DiskCacheStrategy.RESOURCE;
+ case AUTOMATIC:
+ return DiskCacheStrategy.AUTOMATIC;
+ default:
+ return DiskCacheStrategy.AUTOMATIC;
+ }
}
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/layout/ExpandableLayout.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/layout/ExpandableLayout.java
new file mode 100644
index 00000000..7cd764c0
--- /dev/null
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/layout/ExpandableLayout.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xui.widget.layout;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.Interpolator;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+import com.xuexiang.xui.R;
+import com.xuexiang.xui.widget.layout.interpolator.FastOutSlowInInterpolator;
+
+import static com.xuexiang.xui.widget.layout.ExpandableLayout.State.COLLAPSED;
+import static com.xuexiang.xui.widget.layout.ExpandableLayout.State.COLLAPSING;
+import static com.xuexiang.xui.widget.layout.ExpandableLayout.State.EXPANDED;
+import static com.xuexiang.xui.widget.layout.ExpandableLayout.State.EXPANDING;
+
+/**
+ * 可伸缩的布局
+ *
+ * @author xuexiang
+ * @since 2019-11-22 13:41
+ */
+public class ExpandableLayout extends FrameLayout {
+
+ public interface State {
+ /**
+ * 已收缩
+ */
+ int COLLAPSED = 0;
+ /**
+ * 收缩中
+ */
+ int COLLAPSING = 1;
+ /**
+ * 伸展中
+ */
+ int EXPANDING = 2;
+ /**
+ * 已伸展
+ */
+ int EXPANDED = 3;
+ }
+
+ public static final String KEY_SUPER_STATE = "key_super_state";
+ public static final String KEY_EXPANSION = "key_expansion";
+
+ public static final int HORIZONTAL = 0;
+ public static final int VERTICAL = 1;
+
+ /**
+ * 默认伸缩动画持续的时间
+ */
+ private static final int DEFAULT_DURATION = 300;
+
+ /**
+ * 伸缩动画持续的时间
+ */
+ private int mDuration = DEFAULT_DURATION;
+ /**
+ * 视差效果
+ */
+ private float mParallax;
+ /**
+ * 伸缩比率【Value between 0 (收缩) and 1 (伸展) 】
+ */
+ private float mExpansion;
+ /**
+ * 伸缩方向
+ */
+ private int mOrientation;
+ /**
+ * 伸缩状态
+ */
+ private int mState;
+
+ private Interpolator mInterpolator = new FastOutSlowInInterpolator();
+ private ValueAnimator mAnimator;
+ private OnExpansionChangedListener mListener;
+
+ public ExpandableLayout(Context context) {
+ this(context, null);
+ }
+
+ public ExpandableLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ if (attrs != null) {
+ TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ExpandableLayout);
+ mDuration = a.getInt(R.styleable.ExpandableLayout_el_duration, DEFAULT_DURATION);
+ mExpansion = a.getBoolean(R.styleable.ExpandableLayout_el_expanded, false) ? 1 : 0;
+ mOrientation = a.getInt(R.styleable.ExpandableLayout_android_orientation, VERTICAL);
+ mParallax = a.getFloat(R.styleable.ExpandableLayout_el_parallax, 1);
+ a.recycle();
+ mState = mExpansion == 0 ? COLLAPSED : EXPANDED;
+ setParallax(mParallax);
+ }
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ Parcelable superState = super.onSaveInstanceState();
+ Bundle bundle = new Bundle();
+ mExpansion = isExpanded() ? 1 : 0;
+ bundle.putFloat(KEY_EXPANSION, mExpansion);
+ bundle.putParcelable(KEY_SUPER_STATE, superState);
+ return bundle;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable parcelable) {
+ Bundle bundle = (Bundle) parcelable;
+ mExpansion = bundle.getFloat(KEY_EXPANSION);
+ mState = mExpansion == 1 ? EXPANDED : COLLAPSED;
+ Parcelable superState = bundle.getParcelable(KEY_SUPER_STATE);
+ super.onRestoreInstanceState(superState);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ int width = getMeasuredWidth();
+ int height = getMeasuredHeight();
+ int size = mOrientation == LinearLayout.HORIZONTAL ? width : height;
+ setVisibility(mExpansion == 0 && size == 0 ? GONE : VISIBLE);
+ int expansionDelta = size - Math.round(size * mExpansion);
+ if (mParallax > 0) {
+ float parallaxDelta = expansionDelta * mParallax;
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (mOrientation == HORIZONTAL) {
+ int direction = -1;
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1 && getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+ direction = 1;
+ }
+ child.setTranslationX(direction * parallaxDelta);
+ } else {
+ child.setTranslationY(-parallaxDelta);
+ }
+ }
+ }
+
+ if (mOrientation == HORIZONTAL) {
+ setMeasuredDimension(width - expansionDelta, height);
+ } else {
+ setMeasuredDimension(width, height - expansionDelta);
+ }
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ }
+ super.onConfigurationChanged(newConfig);
+ }
+
+ /**
+ * Get mExpansion mState
+ *
+ * @return one of {@link State}
+ */
+ public int getState() {
+ return mState;
+ }
+
+ public boolean isExpanded() {
+ return mState == EXPANDING || mState == EXPANDED;
+ }
+
+ /**
+ * 切换
+ */
+ public void toggle() {
+ toggle(true);
+ }
+
+ public void toggle(boolean animate) {
+ if (isExpanded()) {
+ collapse(animate);
+ } else {
+ expand(animate);
+ }
+ }
+
+ /**
+ * 伸展
+ */
+ public void expand() {
+ expand(true);
+ }
+
+ public void expand(boolean animate) {
+ setExpanded(true, animate);
+ }
+
+ /**
+ * 收缩
+ */
+ public void collapse() {
+ collapse(true);
+ }
+
+ public void collapse(boolean animate) {
+ setExpanded(false, animate);
+ }
+
+ /**
+ * Convenience method - same as calling setExpanded(expanded, true)
+ */
+ public void setExpanded(boolean expand) {
+ setExpanded(expand, true);
+ }
+
+ public void setExpanded(boolean expand, boolean animate) {
+ if (expand == isExpanded()) {
+ return;
+ }
+
+ int targetExpansion = expand ? 1 : 0;
+ if (animate) {
+ animateSize(targetExpansion);
+ } else {
+ setExpansion(targetExpansion);
+ }
+ }
+
+ public int getDuration() {
+ return mDuration;
+ }
+
+ public ExpandableLayout setInterpolator(Interpolator interpolator) {
+ mInterpolator = interpolator;
+ return this;
+ }
+
+ public ExpandableLayout setDuration(int duration) {
+ mDuration = duration;
+ return this;
+ }
+
+ public float getExpansion() {
+ return mExpansion;
+ }
+
+ public void setExpansion(float expansion) {
+ if (mExpansion == expansion) {
+ return;
+ }
+ // Infer mState from previous value
+ float delta = expansion - this.mExpansion;
+ if (expansion == 0) {
+ mState = COLLAPSED;
+ } else if (expansion == 1) {
+ mState = EXPANDED;
+ } else if (delta < 0) {
+ mState = COLLAPSING;
+ } else if (delta > 0) {
+ mState = EXPANDING;
+ }
+ setVisibility(mState == COLLAPSED ? GONE : VISIBLE);
+ mExpansion = expansion;
+ requestLayout();
+
+ if (mListener != null) {
+ mListener.onExpansionChanged(expansion, mState);
+ }
+ }
+
+ public float getParallax() {
+ return mParallax;
+ }
+
+ public ExpandableLayout setParallax(float parallax) {
+ parallax = Math.min(1, Math.max(0, parallax));
+ mParallax = parallax;
+ return this;
+ }
+
+ public int getOrientation() {
+ return mOrientation;
+ }
+
+ public ExpandableLayout setOrientation(int orientation) {
+ if (orientation < 0 || orientation > 1) {
+ throw new IllegalArgumentException("Orientation must be either 0 (horizontal) or 1 (vertical)");
+ }
+ mOrientation = orientation;
+ return this;
+ }
+
+ /**
+ * 设置伸缩比率变化监听
+ * @param listener
+ * @return
+ */
+ public ExpandableLayout setOnExpansionChangedListener(OnExpansionChangedListener listener) {
+ mListener = listener;
+ return this;
+ }
+
+ private void animateSize(int targetExpansion) {
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ mAnimator = null;
+ }
+
+ mAnimator = ValueAnimator.ofFloat(mExpansion, targetExpansion);
+ mAnimator.setInterpolator(mInterpolator);
+ mAnimator.setDuration(mDuration);
+
+ mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ setExpansion((float) valueAnimator.getAnimatedValue());
+ }
+ });
+
+ mAnimator.addListener(new ExpansionListener(targetExpansion));
+
+ mAnimator.start();
+ }
+
+ /**
+ * 伸缩比率变化监听
+ */
+ public interface OnExpansionChangedListener {
+ /**
+ * 伸缩比率变化
+ *
+ * @param expansion 伸缩比率【Value between 0 (收缩) and 1 (伸展) 】
+ * @param state 伸缩状态
+ */
+ void onExpansionChanged(float expansion, int state);
+ }
+
+ private class ExpansionListener implements Animator.AnimatorListener {
+ private int targetExpansion;
+ private boolean canceled;
+
+ public ExpansionListener(int targetExpansion) {
+ this.targetExpansion = targetExpansion;
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mState = targetExpansion == 0 ? COLLAPSING : EXPANDING;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!canceled) {
+ mState = targetExpansion == 0 ? COLLAPSED : EXPANDED;
+ setExpansion(targetExpansion);
+ }
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ canceled = true;
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+ }
+}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/layout/interpolator/FastOutSlowInInterpolator.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/layout/interpolator/FastOutSlowInInterpolator.java
new file mode 100644
index 00000000..5329a766
--- /dev/null
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/layout/interpolator/FastOutSlowInInterpolator.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xui.widget.layout.interpolator;
+
+/**
+ * Interpolator corresponding to {@link android.R.interpolator#fast_out_slow_in}.
+ *
+ * Uses a lookup table for the Bezier curve from (0,0) to (1,1) with control points:
+ * P0 (0, 0)
+ * P1 (0.4, 0)
+ * P2 (0.2, 1.0)
+ * P3 (1.0, 1.0)
+ */
+public class FastOutSlowInInterpolator extends LookupTableInterpolator {
+
+ /**
+ * Lookup table values sampled with x at regular intervals between 0 and 1 for a total of
+ * 201 points.
+ */
+ private static final float[] VALUES = new float[] {
+ 0.0000f, 0.0001f, 0.0002f, 0.0005f, 0.0009f, 0.0014f, 0.0020f,
+ 0.0027f, 0.0036f, 0.0046f, 0.0058f, 0.0071f, 0.0085f, 0.0101f,
+ 0.0118f, 0.0137f, 0.0158f, 0.0180f, 0.0205f, 0.0231f, 0.0259f,
+ 0.0289f, 0.0321f, 0.0355f, 0.0391f, 0.0430f, 0.0471f, 0.0514f,
+ 0.0560f, 0.0608f, 0.0660f, 0.0714f, 0.0771f, 0.0830f, 0.0893f,
+ 0.0959f, 0.1029f, 0.1101f, 0.1177f, 0.1257f, 0.1339f, 0.1426f,
+ 0.1516f, 0.1610f, 0.1707f, 0.1808f, 0.1913f, 0.2021f, 0.2133f,
+ 0.2248f, 0.2366f, 0.2487f, 0.2611f, 0.2738f, 0.2867f, 0.2998f,
+ 0.3131f, 0.3265f, 0.3400f, 0.3536f, 0.3673f, 0.3810f, 0.3946f,
+ 0.4082f, 0.4217f, 0.4352f, 0.4485f, 0.4616f, 0.4746f, 0.4874f,
+ 0.5000f, 0.5124f, 0.5246f, 0.5365f, 0.5482f, 0.5597f, 0.5710f,
+ 0.5820f, 0.5928f, 0.6033f, 0.6136f, 0.6237f, 0.6335f, 0.6431f,
+ 0.6525f, 0.6616f, 0.6706f, 0.6793f, 0.6878f, 0.6961f, 0.7043f,
+ 0.7122f, 0.7199f, 0.7275f, 0.7349f, 0.7421f, 0.7491f, 0.7559f,
+ 0.7626f, 0.7692f, 0.7756f, 0.7818f, 0.7879f, 0.7938f, 0.7996f,
+ 0.8053f, 0.8108f, 0.8162f, 0.8215f, 0.8266f, 0.8317f, 0.8366f,
+ 0.8414f, 0.8461f, 0.8507f, 0.8551f, 0.8595f, 0.8638f, 0.8679f,
+ 0.8720f, 0.8760f, 0.8798f, 0.8836f, 0.8873f, 0.8909f, 0.8945f,
+ 0.8979f, 0.9013f, 0.9046f, 0.9078f, 0.9109f, 0.9139f, 0.9169f,
+ 0.9198f, 0.9227f, 0.9254f, 0.9281f, 0.9307f, 0.9333f, 0.9358f,
+ 0.9382f, 0.9406f, 0.9429f, 0.9452f, 0.9474f, 0.9495f, 0.9516f,
+ 0.9536f, 0.9556f, 0.9575f, 0.9594f, 0.9612f, 0.9629f, 0.9646f,
+ 0.9663f, 0.9679f, 0.9695f, 0.9710f, 0.9725f, 0.9739f, 0.9753f,
+ 0.9766f, 0.9779f, 0.9791f, 0.9803f, 0.9815f, 0.9826f, 0.9837f,
+ 0.9848f, 0.9858f, 0.9867f, 0.9877f, 0.9885f, 0.9894f, 0.9902f,
+ 0.9910f, 0.9917f, 0.9924f, 0.9931f, 0.9937f, 0.9944f, 0.9949f,
+ 0.9955f, 0.9960f, 0.9964f, 0.9969f, 0.9973f, 0.9977f, 0.9980f,
+ 0.9984f, 0.9986f, 0.9989f, 0.9991f, 0.9993f, 0.9995f, 0.9997f,
+ 0.9998f, 0.9999f, 0.9999f, 1.0000f, 1.0000f
+ };
+
+ public FastOutSlowInInterpolator() {
+ super(VALUES);
+ }
+
+}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/layout/interpolator/LookupTableInterpolator.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/layout/interpolator/LookupTableInterpolator.java
new file mode 100644
index 00000000..f1f65e85
--- /dev/null
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/layout/interpolator/LookupTableInterpolator.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xui.widget.layout.interpolator;
+
+import android.view.animation.Interpolator;
+
+/**
+ * An {@link Interpolator} that uses a lookup table to compute an interpolation based on a
+ * given input.
+ */
+abstract class LookupTableInterpolator implements Interpolator {
+
+ private final float[] mValues;
+ private final float mStepSize;
+
+ public LookupTableInterpolator(float[] values) {
+ mValues = values;
+ mStepSize = 1f / (mValues.length - 1);
+ }
+
+ @Override
+ public float getInterpolation(float input) {
+ if (input >= 1.0f) {
+ return 1.0f;
+ }
+ if (input <= 0f) {
+ return 0f;
+ }
+
+ // Calculate index - We use min with length - 2 to avoid IndexOutOfBoundsException when
+ // we lerp (linearly interpolate) in the return statement
+ int position = Math.min((int) (input * (mValues.length - 1)), mValues.length - 2);
+
+ // Calculate values to account for small offsets as the lookup table has discrete values
+ float quantized = position * mStepSize;
+ float diff = input - quantized;
+ float weight = diff / mStepSize;
+
+ // Linearly interpolate between the table values
+ return mValues[position] + weight * (mValues[position + 1] - mValues[position]);
+ }
+
+}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/picker/RulerView.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/picker/RulerView.java
index 2d9ed8d6..be091860 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/picker/RulerView.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/picker/RulerView.java
@@ -39,145 +39,139 @@ public class RulerView extends View implements HasTypeface {
/**
* 2个大刻度之间间距,默认为1
*/
- private int scaleLimit = 1;
+ private int mScaleLimit = 1;
/**
* 尺子高度
*/
- private int rulerHeight = 50;
+ private int mRulerHeight = 50;
/**
* 尺子和屏幕顶部以及结果之间的高度
*/
- private int rulerToResultGap = rulerHeight / 4;
+ private int mRulerToResultGap = mRulerHeight / 4;
/**
* 刻度平分多少份
*/
- private int scaleCount = 10;
+ private int mScaleCount = 10;
/**
* 刻度间距
*/
- private int scaleGap = 10;
+ private int mScaleGap = 10;
/**
* 刻度最小值
*/
- private int minScale = 0;
+ private int mMinScale = 0;
/**
* 第一次显示的刻度
*/
- private float firstScale = 50f;
+ private float mFirstScale = 50f;
/**
* 刻度最大值
*/
- private int maxScale = 100;
+ private int mMaxScale = 100;
/**
* 背景颜色
*/
- private int bgColor;
+ private int mBgColor;
/**
* 小刻度的颜色
*/
- private int smallScaleColor;
+ private int mSmallScaleColor;
/**
* 中刻度的颜色
*/
- private int midScaleColor;
+ private int mMidScaleColor;
/**
* 大刻度的颜色
*/
- private int largeScaleColor;
+ private int mLargeScaleColor;
/**
* 刻度颜色
*/
- private int scaleNumColor;
+ private int mScaleNumColor;
/**
* 结果值颜色
*/
- private int resultNumColor;
+ private int mResultNumColor;
/**
* kg颜色
*/
- private String unit = "kg";
+ private String mUnit = "kg";
/**
* kg颜色
*/
- private int unitColor;
+ private int mUnitColor;
/**
* 小刻度粗细大小
*/
- private int smallScaleStroke = 2;
+ private int mSmallScaleStroke = 2;
/**
* 中刻度粗细大小
*/
- private int midScaleStroke = 3;
+ private int mMidScaleStroke = 3;
/**
* 大刻度粗细大小
*/
- private int largeScaleStroke = 5;
+ private int mLargeScaleStroke = 5;
/**
* 结果字体大小
*/
- private int resultNumTextSize = 20;
+ private int mResultNumTextSize = 20;
/**
* 刻度字体大小
*/
- private int scaleNumTextSize = 16;
+ private int mScaleNumTextSize = 16;
/**
* 单位字体大小
*/
- private int unitTextSize = 13;
+ private int mUnitTextSize = 13;
/**
* 是否显示刻度结果
*/
- private boolean showScaleResult = true;
+ private boolean mShowScaleResult = true;
/**
* 是否背景显示圆角
*/
- private boolean isBgRoundRect = true;
+ private boolean mIsBgRoundRect = true;
/**
* 圆角大小
*/
- private int roundRadius = 10;
+ private int mRoundRadius = 10;
/**
* 结果回调
*/
- private OnChooseResultListener onChooseResultListener;
+ private OnChooseResultListener mOnChooseResultListener;
/**
* 滑动选择刻度
*/
- private float computeScale = -1;
+ private float mComputeScale = -1;
/**
* 当前刻度
*/
- public float currentScale = firstScale;
-
- private ValueAnimator valueAnimator;
- private VelocityTracker velocityTracker = VelocityTracker.obtain();
- private String resultText = String.valueOf(firstScale);
- private Paint bgPaint;
- private Paint smallScalePaint;
- private Paint midScalePaint;
- private Paint lagScalePaint;
- private TextPaint scaleNumPaint;
- private TextPaint resultNumPaint;
- private TextPaint unitPaint;
- private Rect scaleNumRect;
- private Rect resultNumRect;
- private Rect kgRect;
- private RectF bgRect;
- private int height, width;
- private int smallScaleHeight;
- private int midScaleHeight;
- private int lagScaleHeight;
- private int rulerRight = 0;
- private int resultNumRight;
- private float downX;
- private float moveX = 0;
- private float currentX;
- private float lastMoveX = 0;
- private boolean isUp = false;
- private int leftScroll;
- private int rightScroll;
- private int xVelocity;
+ public float mCurrentScale = mFirstScale;
+
+ private ValueAnimator mValueAnimator;
+ private VelocityTracker mVelocityTracker = VelocityTracker.obtain();
+ private String mResultText = String.valueOf(mFirstScale);
+ private Paint mBgPaint;
+ private Paint mSmallScalePaint;
+ private Paint mMidScalePaint;
+ private Paint mLagScalePaint;
+ private TextPaint mScaleNumPaint;
+ private TextPaint mResultNumPaint;
+ private TextPaint mUnitPaint;
+ private Rect mScaleNumRect;
+ private Rect mResultNumRect;
+ private Rect mKgRect;
+ private RectF mBgRect;
+ private int mHeight, mWidth;
+ private int mSmallScaleHeight;
+ private int mMidScaleHeight;
+ private int mLagScaleHeight;
+ private float mDownX;
+ private float mMoveX = 0;
+ private float mLastMoveX = 0;
+ private boolean mIsUp = false;
public RulerView(Context context) {
this(context, null, R.attr.RulerViewStyle);
@@ -201,87 +195,87 @@ public RulerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr
*/
private void initAttrs(AttributeSet attrs, int defStyleAttr) {
TypedArray a = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.RulerView, defStyleAttr, 0);
- scaleLimit = a.getInt(R.styleable.RulerView_rv_scaleLimit, scaleLimit);
- rulerHeight = a.getDimensionPixelSize(R.styleable.RulerView_rv_rulerHeight, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rulerHeight, getResources().getDisplayMetrics()));
- rulerToResultGap = a.getDimensionPixelSize(R.styleable.RulerView_rv_rulerToResultGap, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rulerToResultGap, getResources().getDisplayMetrics()));
- scaleCount = a.getInt(R.styleable.RulerView_rv_scaleCount, scaleCount);
- scaleGap = a.getDimensionPixelSize(R.styleable.RulerView_rv_scaleGap, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scaleGap, getResources().getDisplayMetrics()));
- minScale = a.getInt(R.styleable.RulerView_rv_minScale, minScale) / scaleLimit;
- firstScale = a.getFloat(R.styleable.RulerView_rv_firstScale, firstScale) / scaleLimit;
- maxScale = a.getInt(R.styleable.RulerView_rv_maxScale, maxScale) / scaleLimit;
- bgColor = a.getColor(R.styleable.RulerView_rv_bgColor, ResUtils.getColor(R.color.default_ruler_view_bg_color));
- smallScaleColor = a.getColor(R.styleable.RulerView_rv_smallScaleColor, ResUtils.getColor(R.color.default_ruler_view_small_scale_color));
- midScaleColor = a.getColor(R.styleable.RulerView_rv_midScaleColor, ResUtils.getColor(R.color.default_ruler_view_mid_scale_color));
- largeScaleColor = a.getColor(R.styleable.RulerView_rv_largeScaleColor, ResUtils.getColor(R.color.default_ruler_view_large_scale_color));
- scaleNumColor = a.getColor(R.styleable.RulerView_rv_scaleNumColor, ResUtils.getColor(R.color.default_ruler_view_scale_num_color));
- resultNumColor = a.getColor(R.styleable.RulerView_rv_resultNumColor, ResUtils.getColor(R.color.default_ruler_view_result_num_color));
- unitColor = a.getColor(R.styleable.RulerView_rv_unitColor, ResUtils.getColor(R.color.default_ruler_view_unit_color));
- String tempUnit = unit;
- unit = a.getString(R.styleable.RulerView_rv_unit);
- if (TextUtils.isEmpty(unit)) {
- unit = tempUnit;
+ mScaleLimit = a.getInt(R.styleable.RulerView_rv_scaleLimit, mScaleLimit);
+ mRulerHeight = a.getDimensionPixelSize(R.styleable.RulerView_rv_rulerHeight, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mRulerHeight, getResources().getDisplayMetrics()));
+ mRulerToResultGap = a.getDimensionPixelSize(R.styleable.RulerView_rv_rulerToResultGap, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mRulerToResultGap, getResources().getDisplayMetrics()));
+ mScaleCount = a.getInt(R.styleable.RulerView_rv_scaleCount, mScaleCount);
+ mScaleGap = a.getDimensionPixelSize(R.styleable.RulerView_rv_scaleGap, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mScaleGap, getResources().getDisplayMetrics()));
+ mMinScale = a.getInt(R.styleable.RulerView_rv_minScale, mMinScale) / mScaleLimit;
+ mFirstScale = a.getFloat(R.styleable.RulerView_rv_firstScale, mFirstScale) / mScaleLimit;
+ mMaxScale = a.getInt(R.styleable.RulerView_rv_maxScale, mMaxScale) / mScaleLimit;
+ mBgColor = a.getColor(R.styleable.RulerView_rv_bgColor, ResUtils.getColor(R.color.default_ruler_view_bg_color));
+ mSmallScaleColor = a.getColor(R.styleable.RulerView_rv_smallScaleColor, ResUtils.getColor(R.color.default_ruler_view_small_scale_color));
+ mMidScaleColor = a.getColor(R.styleable.RulerView_rv_midScaleColor, ResUtils.getColor(R.color.default_ruler_view_mid_scale_color));
+ mLargeScaleColor = a.getColor(R.styleable.RulerView_rv_largeScaleColor, ResUtils.getColor(R.color.default_ruler_view_large_scale_color));
+ mScaleNumColor = a.getColor(R.styleable.RulerView_rv_scaleNumColor, ResUtils.getColor(R.color.default_ruler_view_scale_num_color));
+ mResultNumColor = a.getColor(R.styleable.RulerView_rv_resultNumColor, ResUtils.getColor(R.color.default_ruler_view_result_num_color));
+ mUnitColor = a.getColor(R.styleable.RulerView_rv_unitColor, ResUtils.getColor(R.color.default_ruler_view_unit_color));
+ String tempUnit = mUnit;
+ mUnit = a.getString(R.styleable.RulerView_rv_unit);
+ if (TextUtils.isEmpty(mUnit)) {
+ mUnit = tempUnit;
}
- smallScaleStroke = a.getDimensionPixelSize(R.styleable.RulerView_rv_smallScaleStroke, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, smallScaleStroke, getResources().getDisplayMetrics()));
- midScaleStroke = a.getDimensionPixelSize(R.styleable.RulerView_rv_midScaleStroke, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, midScaleStroke, getResources().getDisplayMetrics()));
- largeScaleStroke = a.getDimensionPixelSize(R.styleable.RulerView_rv_largeScaleStroke, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, largeScaleStroke, getResources().getDisplayMetrics()));
- resultNumTextSize = a.getDimensionPixelSize(R.styleable.RulerView_rv_resultNumTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, resultNumTextSize, getResources().getDisplayMetrics()));
- scaleNumTextSize = a.getDimensionPixelSize(R.styleable.RulerView_rv_scaleNumTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, scaleNumTextSize, getResources().getDisplayMetrics()));
- unitTextSize = a.getDimensionPixelSize(R.styleable.RulerView_rv_unitTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, unitTextSize, getResources().getDisplayMetrics()));
- showScaleResult = a.getBoolean(R.styleable.RulerView_rv_showScaleResult, showScaleResult);
- isBgRoundRect = a.getBoolean(R.styleable.RulerView_rv_isBgRoundRect, isBgRoundRect);
- roundRadius = a.getDimensionPixelSize(R.styleable.RulerView_rv_roundRadius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, roundRadius, getResources().getDisplayMetrics()));
+ mSmallScaleStroke = a.getDimensionPixelSize(R.styleable.RulerView_rv_smallScaleStroke, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mSmallScaleStroke, getResources().getDisplayMetrics()));
+ mMidScaleStroke = a.getDimensionPixelSize(R.styleable.RulerView_rv_midScaleStroke, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mMidScaleStroke, getResources().getDisplayMetrics()));
+ mLargeScaleStroke = a.getDimensionPixelSize(R.styleable.RulerView_rv_largeScaleStroke, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mLargeScaleStroke, getResources().getDisplayMetrics()));
+ mResultNumTextSize = a.getDimensionPixelSize(R.styleable.RulerView_rv_resultNumTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mResultNumTextSize, getResources().getDisplayMetrics()));
+ mScaleNumTextSize = a.getDimensionPixelSize(R.styleable.RulerView_rv_scaleNumTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mScaleNumTextSize, getResources().getDisplayMetrics()));
+ mUnitTextSize = a.getDimensionPixelSize(R.styleable.RulerView_rv_unitTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mUnitTextSize, getResources().getDisplayMetrics()));
+ mShowScaleResult = a.getBoolean(R.styleable.RulerView_rv_showScaleResult, mShowScaleResult);
+ mIsBgRoundRect = a.getBoolean(R.styleable.RulerView_rv_isBgRoundRect, mIsBgRoundRect);
+ mRoundRadius = a.getDimensionPixelSize(R.styleable.RulerView_rv_roundRadius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mRoundRadius, getResources().getDisplayMetrics()));
a.recycle();
}
private void init() {
- bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- smallScalePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- midScalePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- lagScalePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- scaleNumPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
- resultNumPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
- unitPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
-
- bgPaint.setColor(bgColor);
- smallScalePaint.setColor(smallScaleColor);
- midScalePaint.setColor(midScaleColor);
- lagScalePaint.setColor(largeScaleColor);
- scaleNumPaint.setColor(scaleNumColor);
- resultNumPaint.setColor(resultNumColor);
- unitPaint.setColor(unitColor);
-
- resultNumPaint.setStyle(Paint.Style.FILL);
- unitPaint.setStyle(Paint.Style.FILL);
- bgPaint.setStyle(Paint.Style.FILL);
- smallScalePaint.setStyle(Paint.Style.FILL);
- midScalePaint.setStyle(Paint.Style.FILL);
- lagScalePaint.setStyle(Paint.Style.FILL);
-
- lagScalePaint.setStrokeCap(Paint.Cap.ROUND);
- midScalePaint.setStrokeCap(Paint.Cap.ROUND);
- smallScalePaint.setStrokeCap(Paint.Cap.ROUND);
-
- smallScalePaint.setStrokeWidth(smallScaleStroke);
- midScalePaint.setStrokeWidth(midScaleStroke);
- lagScalePaint.setStrokeWidth(largeScaleStroke);
-
- resultNumPaint.setTextSize(resultNumTextSize);
- unitPaint.setTextSize(unitTextSize);
- scaleNumPaint.setTextSize(scaleNumTextSize);
-
- bgRect = new RectF();
- resultNumRect = new Rect();
- scaleNumRect = new Rect();
- kgRect = new Rect();
-
- resultNumPaint.getTextBounds(resultText, 0, resultText.length(), resultNumRect);
- unitPaint.getTextBounds(resultText, 0, 1, kgRect);
-
- smallScaleHeight = rulerHeight / 4;
- midScaleHeight = rulerHeight / 2;
- lagScaleHeight = rulerHeight / 2 + 5;
- valueAnimator = new ValueAnimator();
+ mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mSmallScalePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mMidScalePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mLagScalePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mScaleNumPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+ mResultNumPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+ mUnitPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+
+ mBgPaint.setColor(mBgColor);
+ mSmallScalePaint.setColor(mSmallScaleColor);
+ mMidScalePaint.setColor(mMidScaleColor);
+ mLagScalePaint.setColor(mLargeScaleColor);
+ mScaleNumPaint.setColor(mScaleNumColor);
+ mResultNumPaint.setColor(mResultNumColor);
+ mUnitPaint.setColor(mUnitColor);
+
+ mResultNumPaint.setStyle(Paint.Style.FILL);
+ mUnitPaint.setStyle(Paint.Style.FILL);
+ mBgPaint.setStyle(Paint.Style.FILL);
+ mSmallScalePaint.setStyle(Paint.Style.FILL);
+ mMidScalePaint.setStyle(Paint.Style.FILL);
+ mLagScalePaint.setStyle(Paint.Style.FILL);
+
+ mLagScalePaint.setStrokeCap(Paint.Cap.ROUND);
+ mMidScalePaint.setStrokeCap(Paint.Cap.ROUND);
+ mSmallScalePaint.setStrokeCap(Paint.Cap.ROUND);
+
+ mSmallScalePaint.setStrokeWidth(mSmallScaleStroke);
+ mMidScalePaint.setStrokeWidth(mMidScaleStroke);
+ mLagScalePaint.setStrokeWidth(mLargeScaleStroke);
+
+ mResultNumPaint.setTextSize(mResultNumTextSize);
+ mUnitPaint.setTextSize(mUnitTextSize);
+ mScaleNumPaint.setTextSize(mScaleNumTextSize);
+
+ mBgRect = new RectF();
+ mResultNumRect = new Rect();
+ mScaleNumRect = new Rect();
+ mKgRect = new Rect();
+
+ mResultNumPaint.getTextBounds(mResultText, 0, mResultText.length(), mResultNumRect);
+ mUnitPaint.getTextBounds(mResultText, 0, 1, mKgRect);
+
+ mSmallScaleHeight = mRulerHeight / 4;
+ mMidScaleHeight = mRulerHeight / 2;
+ mLagScaleHeight = mRulerHeight / 2 + 5;
+ mValueAnimator = new ValueAnimator();
}
@@ -294,19 +288,19 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
switch (heightModule) {
case MeasureSpec.AT_MOST:
- height = rulerHeight + (showScaleResult ? resultNumRect.height() : 0) + rulerToResultGap * 2 + getPaddingTop() + getPaddingBottom();
+ mHeight = mRulerHeight + (mShowScaleResult ? mResultNumRect.height() : 0) + mRulerToResultGap * 2 + getPaddingTop() + getPaddingBottom();
break;
case MeasureSpec.UNSPECIFIED:
case MeasureSpec.EXACTLY:
- height = heightSize + getPaddingTop() + getPaddingBottom();
+ mHeight = heightSize + getPaddingTop() + getPaddingBottom();
break;
default:
break;
}
- width = widthSize + getPaddingLeft() + getPaddingRight();
+ mWidth = widthSize + getPaddingLeft() + getPaddingRight();
- setMeasuredDimension(width, height);
+ setMeasuredDimension(mWidth, mHeight);
}
@@ -314,7 +308,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
protected void onDraw(Canvas canvas) {
drawBg(canvas);
drawScaleAndNum(canvas);
- drawResultText(canvas, resultText);
+ drawResultText(canvas, mResultText);
}
@Override
@@ -324,34 +318,34 @@ public boolean onTouchEvent(MotionEvent event) {
getParent().requestDisallowInterceptTouchEvent(true);
}
- currentX = event.getX();
- isUp = false;
- velocityTracker.computeCurrentVelocity(500);
- velocityTracker.addMovement(event);
+ float currentX = event.getX();
+ mIsUp = false;
+ mVelocityTracker.computeCurrentVelocity(500);
+ mVelocityTracker.addMovement(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//按下时如果属性动画还没执行完,就终止,记录下当前按下点的位置
- if (valueAnimator != null && valueAnimator.isRunning()) {
- valueAnimator.end();
- valueAnimator.cancel();
+ if (mValueAnimator != null && mValueAnimator.isRunning()) {
+ mValueAnimator.end();
+ mValueAnimator.cancel();
}
- downX = event.getX();
+ mDownX = event.getX();
break;
case MotionEvent.ACTION_MOVE:
//滑动时候,通过假设的滑动距离,做超出左边界以及右边界的限制。
- moveX = currentX - downX + lastMoveX;
- if (moveX >= width / 2) {
- moveX = width / 2;
- } else if (moveX <= getWhichScaleMoveX(maxScale)) {
- moveX = getWhichScaleMoveX(maxScale);
+ mMoveX = currentX - mDownX + mLastMoveX;
+ if (mMoveX >= mWidth / 2) {
+ mMoveX = mWidth / 2;
+ } else if (mMoveX <= getWhichScaleMoveX(mMaxScale)) {
+ mMoveX = getWhichScaleMoveX(mMaxScale);
}
break;
case MotionEvent.ACTION_UP:
//手指抬起时候制造惯性滑动
- lastMoveX = moveX;
- xVelocity = (int) velocityTracker.getXVelocity();
+ mLastMoveX = mMoveX;
+ int xVelocity = (int) mVelocityTracker.getXVelocity();
autoVelocityScroll(xVelocity);
- velocityTracker.clear();
+ mVelocityTracker.clear();
break;
default:
break;
@@ -363,213 +357,213 @@ public boolean onTouchEvent(MotionEvent event) {
private void autoVelocityScroll(int xVelocity) {
//惯性滑动的代码,速率和滑动距离,以及滑动时间需要控制的很好,应该网上已经有关于这方面的算法了吧。。这里是经过N次测试调节出来的惯性滑动
if (Math.abs(xVelocity) < 50) {
- isUp = true;
+ mIsUp = true;
return;
}
- if (valueAnimator.isRunning()) {
+ if (mValueAnimator.isRunning()) {
return;
}
- valueAnimator = ValueAnimator.ofInt(0, xVelocity / 20).setDuration(Math.abs(xVelocity / 10));
- valueAnimator.setInterpolator(new DecelerateInterpolator());
- valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ mValueAnimator = ValueAnimator.ofInt(0, xVelocity / 20).setDuration(Math.abs(xVelocity / 10));
+ mValueAnimator.setInterpolator(new DecelerateInterpolator());
+ mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
- moveX += (int) animation.getAnimatedValue();
- if (moveX >= width / 2) {
- moveX = width / 2;
- } else if (moveX <= getWhichScaleMoveX(maxScale)) {
- moveX = getWhichScaleMoveX(maxScale);
+ mMoveX += (int) animation.getAnimatedValue();
+ if (mMoveX >= mWidth / 2) {
+ mMoveX = mWidth / 2;
+ } else if (mMoveX <= getWhichScaleMoveX(mMaxScale)) {
+ mMoveX = getWhichScaleMoveX(mMaxScale);
}
- lastMoveX = moveX;
+ mLastMoveX = mMoveX;
invalidate();
}
});
- valueAnimator.addListener(new AnimatorListenerAdapter() {
+ mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- isUp = true;
+ mIsUp = true;
invalidate();
}
});
- valueAnimator.start();
+ mValueAnimator.start();
}
private float getWhichScaleMoveX(float scale) {
- return width / 2 - scaleGap * scaleCount * (scale - minScale);
+ return mWidth / 2 - mScaleGap * mScaleCount * (scale - mMinScale);
}
private void drawScaleAndNum(Canvas canvas) {
- canvas.translate(0, (showScaleResult ? resultNumRect.height() : 0) + rulerToResultGap);//移动画布到结果值的下面
+ canvas.translate(0, (mShowScaleResult ? mResultNumRect.height() : 0) + mRulerToResultGap);//移动画布到结果值的下面
int num1;//确定刻度位置
float num2;
- if (firstScale != -1) { //第一次进来的时候计算出默认刻度对应的假设滑动的距离moveX
- moveX = getWhichScaleMoveX(firstScale); //如果设置了默认滑动位置,计算出需要滑动的距离
- lastMoveX = moveX;
- firstScale = -1; //将结果置为-1,下次不再计算初始位置
+ if (mFirstScale != -1) { //第一次进来的时候计算出默认刻度对应的假设滑动的距离moveX
+ mMoveX = getWhichScaleMoveX(mFirstScale); //如果设置了默认滑动位置,计算出需要滑动的距离
+ mLastMoveX = mMoveX;
+ mFirstScale = -1; //将结果置为-1,下次不再计算初始位置
}
- if (computeScale != -1) {//弹性滑动到目标刻度
- lastMoveX = moveX;
- if (valueAnimator != null && !valueAnimator.isRunning()) {
- valueAnimator = ValueAnimator.ofFloat(getWhichScaleMoveX(currentScale), getWhichScaleMoveX(computeScale));
- valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ if (mComputeScale != -1) {//弹性滑动到目标刻度
+ mLastMoveX = mMoveX;
+ if (mValueAnimator != null && !mValueAnimator.isRunning()) {
+ mValueAnimator = ValueAnimator.ofFloat(getWhichScaleMoveX(mCurrentScale), getWhichScaleMoveX(mComputeScale));
+ mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
- moveX = (float) animation.getAnimatedValue();
- lastMoveX = moveX;
+ mMoveX = (float) animation.getAnimatedValue();
+ mLastMoveX = mMoveX;
invalidate();
}
});
- valueAnimator.addListener(new AnimatorListenerAdapter() {
+ mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
//这里是滑动结束时候回调给使用者的结果值
- computeScale = -1;
+ mComputeScale = -1;
}
});
- valueAnimator.setDuration(Math.abs((long) ((getWhichScaleMoveX(computeScale) - getWhichScaleMoveX(currentScale)) / 100)));
- valueAnimator.start();
+ mValueAnimator.setDuration(Math.abs((long) ((getWhichScaleMoveX(mComputeScale) - getWhichScaleMoveX(mCurrentScale)) / 100)));
+ mValueAnimator.start();
}
}
- num1 = -(int) (moveX / scaleGap); //滑动刻度的整数部分
- num2 = (moveX % scaleGap); //滑动刻度的小数部分
+ num1 = -(int) (mMoveX / mScaleGap); //滑动刻度的整数部分
+ num2 = (mMoveX % mScaleGap); //滑动刻度的小数部分
canvas.save(); //保存当前画布
- rulerRight = 0; //准备开始绘制当前屏幕,从最左面开始
+ int rulerRight = 0; //准备开始绘制当前屏幕,从最左面开始
- if (isUp) { //这部分代码主要是计算手指抬起时,惯性滑动结束时,刻度需要停留的位置
- num2 = ((moveX - width / 2 % scaleGap) % scaleGap); //计算滑动位置距离整点刻度的小数部分距离
+ if (mIsUp) { //这部分代码主要是计算手指抬起时,惯性滑动结束时,刻度需要停留的位置
+ num2 = ((mMoveX - mWidth / 2 % mScaleGap) % mScaleGap); //计算滑动位置距离整点刻度的小数部分距离
if (num2 <= 0) {
- num2 = scaleGap - Math.abs(num2);
+ num2 = mScaleGap - Math.abs(num2);
}
- leftScroll = (int) Math.abs(num2); //当前滑动位置距离左边整点刻度的距离
- rightScroll = (int) (scaleGap - Math.abs(num2)); //当前滑动位置距离右边整点刻度的距离
+ int leftScroll = (int) Math.abs(num2); //当前滑动位置距离左边整点刻度的距离
+ int rightScroll = (int) (mScaleGap - Math.abs(num2)); //当前滑动位置距离右边整点刻度的距离
- float moveX2 = num2 <= scaleGap / 2 ? moveX - leftScroll : moveX + rightScroll; //最终计算出当前位置到整点刻度位置需要滑动的距离
+ float moveX2 = num2 <= mScaleGap / 2 ? mMoveX - leftScroll : mMoveX + rightScroll; //最终计算出当前位置到整点刻度位置需要滑动的距离
- if (valueAnimator != null && !valueAnimator.isRunning()) { //手指抬起,并且当前没有惯性滑动在进行,创建一个惯性滑动
- valueAnimator = ValueAnimator.ofFloat(moveX, moveX2);
- valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ if (mValueAnimator != null && !mValueAnimator.isRunning()) { //手指抬起,并且当前没有惯性滑动在进行,创建一个惯性滑动
+ mValueAnimator = ValueAnimator.ofFloat(mMoveX, moveX2);
+ mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
- moveX = (float) animation.getAnimatedValue(); //不断滑动去更新新的位置
- lastMoveX = moveX;
+ mMoveX = (float) animation.getAnimatedValue(); //不断滑动去更新新的位置
+ mLastMoveX = mMoveX;
invalidate();
}
});
- valueAnimator.addListener(new AnimatorListenerAdapter() { //增加一个监听,用来返回给使用者滑动结束后的最终结果刻度值
+ mValueAnimator.addListener(new AnimatorListenerAdapter() { //增加一个监听,用来返回给使用者滑动结束后的最终结果刻度值
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
//这里是滑动结束时候回调给使用者的结果值
- if (onChooseResultListener != null) {
- onChooseResultListener.onEndResult(resultText);
+ if (mOnChooseResultListener != null) {
+ mOnChooseResultListener.onEndResult(mResultText);
}
}
});
- valueAnimator.setDuration(300);
- valueAnimator.start();
- isUp = false;
+ mValueAnimator.setDuration(300);
+ mValueAnimator.start();
+ mIsUp = false;
}
-
- num1 = (int) -(moveX / scaleGap); //重新计算当前滑动位置的整数以及小数位置
- num2 = (moveX % scaleGap);
+ //重新计算当前滑动位置的整数以及小数位置
+ num1 = (int) -(mMoveX / mScaleGap);
+ num2 = (mMoveX % mScaleGap);
}
-
- canvas.translate(num2, 0); //不加该偏移的话,滑动时刻度不会落在0~1之间只会落在整数上面,其实这个都能设置一种模式了,毕竟初衷就是指针不会落在小数上面
+ //不加该偏移的话,滑动时刻度不会落在0~1之间只会落在整数上面,其实这个都能设置一种模式了,毕竟初衷就是指针不会落在小数上面
+ canvas.translate(num2, 0);
//这里是滑动时候不断回调给使用者的结果值
- currentScale = new WeakReference<>(new BigDecimal(((width / 2 - moveX) / (scaleGap * scaleCount) + minScale) * scaleLimit)).get().setScale(1, BigDecimal.ROUND_HALF_UP).floatValue();
+ mCurrentScale = new WeakReference<>(new BigDecimal(((mWidth / 2 - mMoveX) / (mScaleGap * mScaleCount) + mMinScale) * mScaleLimit)).get().setScale(1, BigDecimal.ROUND_HALF_UP).floatValue();
- resultText = String.valueOf(currentScale);
+ mResultText = String.valueOf(mCurrentScale);
- if (onChooseResultListener != null) {
- onChooseResultListener.onScrollResult(resultText); //接口不断回调给使用者结果值
+ if (mOnChooseResultListener != null) {
+ mOnChooseResultListener.onScrollResult(mResultText); //接口不断回调给使用者结果值
}
- //绘制当前屏幕可见刻度,不需要裁剪屏幕,while循环只会执行·屏幕宽度/刻度宽度·次,大部分的绘制都是if(curDis= 0 && rulerRight < moveX - scaleGap) || width / 2 - rulerRight <= getWhichScaleMoveX(maxScale + 1) - moveX) {
+ //绘制当前屏幕可见刻度,不需要裁剪屏幕,while循环只会执行·屏幕宽度/刻度宽度·次,大部分的绘制都是if(curDis= 0 && rulerRight < mMoveX - mScaleGap) || mWidth / 2 - rulerRight <= getWhichScaleMoveX(mMaxScale + 1) - mMoveX) {
//当滑动出范围的话,不绘制,去除左右边界
} else {
//绘制刻度,绘制刻度数字
- canvas.drawLine(0, 0, 0, midScaleHeight, midScalePaint);
- scaleNumPaint.getTextBounds(num1 / scaleGap + minScale + "", 0, (num1 / scaleGap + minScale + "").length(), scaleNumRect);
- canvas.drawText((num1 / scaleCount + minScale) * scaleLimit + "", -scaleNumRect.width() / 2, lagScaleHeight +
- (rulerHeight - lagScaleHeight) / 2 + scaleNumRect.height(), scaleNumPaint);
+ canvas.drawLine(0, 0, 0, mMidScaleHeight, mMidScalePaint);
+ mScaleNumPaint.getTextBounds(num1 / mScaleGap + mMinScale + "", 0, (num1 / mScaleGap + mMinScale + "").length(), mScaleNumRect);
+ canvas.drawText((num1 / mScaleCount + mMinScale) * mScaleLimit + "", -mScaleNumRect.width() / 2, mLagScaleHeight +
+ (mRulerHeight - mLagScaleHeight) / 2 + mScaleNumRect.height(), mScaleNumPaint);
}
} else { //绘制小数刻度
- if ((moveX >= 0 && rulerRight < moveX) || width / 2 - rulerRight < getWhichScaleMoveX(maxScale) - moveX) {
+ if ((mMoveX >= 0 && rulerRight < mMoveX) || mWidth / 2 - rulerRight < getWhichScaleMoveX(mMaxScale) - mMoveX) {
//当滑动出范围的话,不绘制,去除左右边界
} else {
//绘制小数刻度
- canvas.drawLine(0, 0, 0, smallScaleHeight, smallScalePaint);
+ canvas.drawLine(0, 0, 0, mSmallScaleHeight, mSmallScalePaint);
}
}
++num1; //刻度加1
- rulerRight += scaleGap; //绘制屏幕的距离在原有基础上+1个刻度间距
- canvas.translate(scaleGap, 0); //移动画布到下一个刻度
+ rulerRight += mScaleGap; //绘制屏幕的距离在原有基础上+1个刻度间距
+ canvas.translate(mScaleGap, 0); //移动画布到下一个刻度
}
canvas.restore();
//绘制屏幕中间用来选中刻度的最大刻度
- canvas.drawLine(width / 2, 0, width / 2, lagScaleHeight, lagScalePaint);
+ canvas.drawLine(mWidth / 2, 0, mWidth / 2, mLagScaleHeight, mLagScalePaint);
}
//绘制上面的结果 结果值+单位
private void drawResultText(Canvas canvas, String resultText) {
- if (!showScaleResult) { //判断用户是否设置需要显示当前刻度值,如果否则取消绘制
+ if (!mShowScaleResult) { //判断用户是否设置需要显示当前刻度值,如果否则取消绘制
return;
}
- canvas.translate(0, -resultNumRect.height() - rulerToResultGap / 2); //移动画布到正确的位置来绘制结果值
- resultNumPaint.getTextBounds(resultText, 0, resultText.length(), resultNumRect);
- canvas.drawText(resultText, width / 2 - resultNumRect.width() / 2, resultNumRect.height(), //绘制当前刻度结果值
- resultNumPaint);
- resultNumRight = width / 2 + resultNumRect.width() / 2 + 10;
- canvas.drawText(unit, resultNumRight, kgRect.height() + 2, unitPaint); //在当前刻度结果值的又面10px的位置绘制单位
+ canvas.translate(0, -mResultNumRect.height() - mRulerToResultGap / 2); //移动画布到正确的位置来绘制结果值
+ mResultNumPaint.getTextBounds(resultText, 0, resultText.length(), mResultNumRect);
+ canvas.drawText(resultText, mWidth / 2 - mResultNumRect.width() / 2, mResultNumRect.height(), //绘制当前刻度结果值
+ mResultNumPaint);
+ int resultNumRight = mWidth / 2 + mResultNumRect.width() / 2 + 10;
+ canvas.drawText(mUnit, resultNumRight, mKgRect.height() + 2, mUnitPaint); //在当前刻度结果值的又面10px的位置绘制单位
}
private void drawBg(Canvas canvas) {
- bgRect.set(0, 0, width, height);
- if (isBgRoundRect) {
+ mBgRect.set(0, 0, mWidth, mHeight);
+ if (mIsBgRoundRect) {
//椭圆的用于圆形角x-radius
- canvas.drawRoundRect(bgRect, roundRadius, roundRadius, bgPaint);
+ canvas.drawRoundRect(mBgRect, mRoundRadius, mRoundRadius, mBgPaint);
} else {
- canvas.drawRect(bgRect, bgPaint);
+ canvas.drawRect(mBgRect, mBgPaint);
}
}
private void computeScrollTo(float scale) {
- scale = scale / scaleLimit;
- if (scale < minScale || scale > maxScale) {
+ scale = scale / mScaleLimit;
+ if (scale < mMinScale || scale > mMaxScale) {
return;
}
- computeScale = scale;
+ mComputeScale = scale;
invalidate();
}
@Override
public void setTypeface(Typeface typeface) {
- if (resultNumPaint != null) {
- resultNumPaint.setTypeface(typeface);
+ if (mResultNumPaint != null) {
+ mResultNumPaint.setTypeface(typeface);
}
- if (unitPaint != null) {
- unitPaint.setTypeface(typeface);
+ if (mUnitPaint != null) {
+ mUnitPaint.setTypeface(typeface);
}
- if (scaleNumPaint != null) {
- scaleNumPaint.setTypeface(typeface);
+ if (mScaleNumPaint != null) {
+ mScaleNumPaint.setTypeface(typeface);
}
}
@@ -593,121 +587,121 @@ public interface OnChooseResultListener {
}
public void setRulerHeight(int rulerHeight) {
- this.rulerHeight = rulerHeight;
+ this.mRulerHeight = rulerHeight;
invalidate();
}
public void setRulerToResultGap(int rulerToResultGap) {
- this.rulerToResultGap = rulerToResultGap;
+ this.mRulerToResultGap = rulerToResultGap;
invalidate();
}
public void setScaleCount(int scaleCount) {
- this.scaleCount = scaleCount;
+ this.mScaleCount = scaleCount;
invalidate();
}
public void setScaleGap(int scaleGap) {
- this.scaleGap = scaleGap;
+ this.mScaleGap = scaleGap;
invalidate();
}
public void setMinScale(int minScale) {
- this.minScale = minScale;
+ this.mMinScale = minScale;
invalidate();
}
public void setFirstScale(float firstScale) {
- this.firstScale = firstScale;
+ this.mFirstScale = firstScale;
invalidate();
}
public void setMaxScale(int maxScale) {
- this.maxScale = maxScale;
+ this.mMaxScale = maxScale;
invalidate();
}
public void setBgColor(int bgColor) {
- this.bgColor = bgColor;
+ this.mBgColor = bgColor;
invalidate();
}
public void setSmallScaleColor(int smallScaleColor) {
- this.smallScaleColor = smallScaleColor;
+ this.mSmallScaleColor = smallScaleColor;
invalidate();
}
public void setMidScaleColor(int midScaleColor) {
- this.midScaleColor = midScaleColor;
+ this.mMidScaleColor = midScaleColor;
invalidate();
}
public void setLargeScaleColor(int largeScaleColor) {
- this.largeScaleColor = largeScaleColor;
+ this.mLargeScaleColor = largeScaleColor;
}
public void setScaleNumColor(int scaleNumColor) {
- this.scaleNumColor = scaleNumColor;
+ this.mScaleNumColor = scaleNumColor;
invalidate();
}
public void setResultNumColor(int resultNumColor) {
- this.resultNumColor = resultNumColor;
+ this.mResultNumColor = resultNumColor;
invalidate();
}
public void setUnit(String unit) {
- this.unit = unit;
+ this.mUnit = unit;
invalidate();
}
public void setUnitColor(int unitColor) {
- this.unitColor = unitColor;
+ this.mUnitColor = unitColor;
invalidate();
}
public void setSmallScaleStroke(int smallScaleStroke) {
- this.smallScaleStroke = smallScaleStroke;
+ this.mSmallScaleStroke = smallScaleStroke;
invalidate();
}
public void setMidScaleStroke(int midScaleStroke) {
- this.midScaleStroke = midScaleStroke;
+ this.mMidScaleStroke = midScaleStroke;
invalidate();
}
public void setLargeScaleStroke(int largeScaleStroke) {
- this.largeScaleStroke = largeScaleStroke;
+ this.mLargeScaleStroke = largeScaleStroke;
invalidate();
}
public void setResultNumTextSize(int resultNumTextSize) {
- this.resultNumTextSize = resultNumTextSize;
+ this.mResultNumTextSize = resultNumTextSize;
invalidate();
}
public void setScaleNumTextSize(int scaleNumTextSize) {
- this.scaleNumTextSize = scaleNumTextSize;
+ this.mScaleNumTextSize = scaleNumTextSize;
invalidate();
}
public void setUnitTextSize(int unitTextSize) {
- this.unitTextSize = unitTextSize;
+ this.mUnitTextSize = unitTextSize;
invalidate();
}
public void setShowScaleResult(boolean showScaleResult) {
- this.showScaleResult = showScaleResult;
+ this.mShowScaleResult = showScaleResult;
invalidate();
}
public void setIsBgRoundRect(boolean bgRoundRect) {
- isBgRoundRect = bgRoundRect;
+ mIsBgRoundRect = bgRoundRect;
invalidate();
}
public void setScaleLimit(int scaleLimit) {
- this.scaleLimit = scaleLimit;
+ this.mScaleLimit = scaleLimit;
invalidate();
}
@@ -726,7 +720,7 @@ public void setCurrentValue(float value) {
* @return
*/
public float getCurrentValue() {
- return currentScale;
+ return mCurrentScale;
}
/**
@@ -735,7 +729,7 @@ public float getCurrentValue() {
* @return
*/
public String getSelectValue() {
- return resultText;
+ return mResultText;
}
/**
@@ -745,7 +739,7 @@ public String getSelectValue() {
* @return
*/
public RulerView setOnChooseResultListener(OnChooseResultListener onChooseResultListener) {
- this.onChooseResultListener = onChooseResultListener;
+ this.mOnChooseResultListener = onChooseResultListener;
return this;
}
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUIExpandableListPopup.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUIExpandableListPopup.java
new file mode 100644
index 00000000..d7d6c684
--- /dev/null
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUIExpandableListPopup.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xui.widget.popupwindow.popup;
+
+import android.content.Context;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.webkit.WebView;
+import android.widget.ExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.FrameLayout;
+
+import com.xuexiang.xui.R;
+import com.xuexiang.xui.XUI;
+import com.xuexiang.xui.utils.DensityUtils;
+import com.xuexiang.xui.utils.ThemeUtils;
+import com.xuexiang.xui.widget.XUIWrapContentExpandableListView;
+
+/**
+ * 继承自 {@link XUIPopup},在 {@link XUIPopup} 的基础上,支持显示一个可伸缩的列表。
+ *
+ * @author xuexiang
+ * @since 2019-11-09 18:05
+ */
+public class XUIExpandableListPopup extends XUIPopup {
+
+ protected ExpandableListView mExpandableListView;
+ protected ExpandableListAdapter mAdapter;
+ private boolean mHasDivider;
+
+ public XUIExpandableListPopup(Context context) {
+ super(context);
+ }
+
+ /**
+ * 构造方法.
+ *
+ * @param context Context
+ * @param direction
+ */
+ public XUIExpandableListPopup(Context context, int direction, ExpandableListAdapter adapter) {
+ super(context, direction);
+ mAdapter = adapter;
+ }
+
+ public XUIExpandableListPopup(Context context, ExpandableListAdapter adapter) {
+ super(context);
+ mAdapter = adapter;
+ }
+
+ /**
+ * 创建弹窗
+ *
+ * @param width 弹窗的宽度
+ * @param maxHeight 弹窗最大的高度
+ * @param onChildClickListener 子列表点击的监听
+ * @return
+ */
+ public T create(int width, int maxHeight, ExpandableListView.OnChildClickListener onChildClickListener) {
+ create(width, maxHeight);
+ mExpandableListView.setOnChildClickListener(onChildClickListener);
+ return (T) this;
+ }
+
+ /**
+ * 创建弹窗
+ *
+ * @param width 弹窗的宽度
+ * @return
+ */
+ public T create(int width) {
+ return create(width, 0);
+ }
+
+ /**
+ * 创建弹窗
+ *
+ * @param width 弹窗的宽度
+ * @param maxHeight 弹窗最大的高度
+ * @return
+ */
+ protected T create(int width, int maxHeight) {
+ int margin = DensityUtils.dp2px(getContext(), 5);
+ if (maxHeight != 0) {
+ mExpandableListView = new XUIWrapContentExpandableListView(getContext(), maxHeight);
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(width, maxHeight);
+ lp.setMargins(0, margin, 0, margin);
+ mExpandableListView.setLayoutParams(lp);
+ } else {
+ mExpandableListView = new XUIWrapContentExpandableListView(getContext());
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(width, FrameLayout.LayoutParams.WRAP_CONTENT);
+ lp.setMargins(0, margin, 0, margin);
+ mExpandableListView.setLayoutParams(lp);
+ }
+ mExpandableListView.setPadding(margin, 0, margin, 0);
+ mExpandableListView.setAdapter(mAdapter);
+ mExpandableListView.setGroupIndicator(null);
+ mExpandableListView.setVerticalScrollBarEnabled(false);
+ mExpandableListView.setOverScrollMode(WebView.OVER_SCROLL_NEVER);
+ updateDivider(mExpandableListView);
+ setContentView(mExpandableListView);
+ return (T) this;
+ }
+
+ /**
+ * 设置是否有分割线
+ *
+ * @return
+ */
+ public T setHasDivider(boolean hasDivider) {
+ mHasDivider = hasDivider;
+ if (mExpandableListView != null) {
+ updateDivider(mExpandableListView);
+ }
+ return (T) this;
+ }
+
+ private void updateDivider(ExpandableListView listView) {
+ if (mHasDivider) {
+ listView.setDivider(new ColorDrawable(ThemeUtils.resolveColor(getContext(), R.attr.xui_config_color_separator_light)));
+ listView.setChildDivider(new ColorDrawable(ThemeUtils.resolveColor(getContext(), R.attr.xui_config_color_separator_light)));
+ listView.setDividerHeight(DensityUtils.dp2px(getContext(), XUI.isTablet() ? 1F : 0.5F));
+ } else {
+ listView.setDivider(null);
+ listView.setChildDivider(null);
+ }
+ }
+
+ /**
+ * 设置Group分割线的资源
+ *
+ * @param divider
+ * @return
+ */
+ public T setGroupDivider(Drawable divider) {
+ if (mExpandableListView != null) {
+ mExpandableListView.setDivider(divider);
+ }
+ return (T) this;
+ }
+
+ /**
+ * 设置Child分割线的资源
+ *
+ * @param divider
+ * @return
+ */
+ public T setChildDivider(Drawable divider) {
+ if (mExpandableListView != null) {
+ mExpandableListView.setChildDivider(divider);
+ }
+ return (T) this;
+ }
+
+ /**
+ * 设置分割线的高度
+ *
+ * @param dividerHeight
+ * @return
+ */
+ public T setDividerHeight(int dividerHeight) {
+ if (mExpandableListView != null) {
+ mExpandableListView.setDividerHeight(dividerHeight);
+ }
+ return (T) this;
+ }
+
+ public T setOnChildClickListener(ExpandableListView.OnChildClickListener onChildClickListener) {
+ if (mExpandableListView != null) {
+ mExpandableListView.setOnChildClickListener(onChildClickListener);
+ }
+ return (T) this;
+ }
+
+ public T setOnGroupClickListener(ExpandableListView.OnGroupClickListener onGroupClickListener) {
+ if (mExpandableListView != null) {
+ mExpandableListView.setOnGroupClickListener(onGroupClickListener);
+ }
+ return (T) this;
+ }
+
+ /**
+ * 设置是否只展开一个
+ *
+ * @param enable
+ * @return
+ */
+ public T setEnableOnlyExpandOne(boolean enable) {
+ if (mExpandableListView != null) {
+ if (enable) {
+ mExpandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
+ @Override
+ public void onGroupExpand(int groupPosition) {
+ expandOnlyOne(groupPosition);
+ }
+ });
+ } else {
+ mExpandableListView.setOnGroupExpandListener(null);
+ }
+ }
+ return (T) this;
+ }
+
+ /**
+ * 只展开一个
+ *
+ * @param expandedPosition
+ * @return
+ */
+ public boolean expandOnlyOne(int expandedPosition) {
+ if (mExpandableListView == null) {
+ return false;
+ }
+ boolean result = true;
+ int groupLength = mExpandableListView.getExpandableListAdapter().getGroupCount();
+ for (int i = 0; i < groupLength; i++) {
+ if (i != expandedPosition && mExpandableListView.isGroupExpanded(i)) {
+ result &= mExpandableListView.collapseGroup(i);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 展开所有组
+ */
+ public void expandAllGroup() {
+ if (mExpandableListView != null) {
+ int groupLength = mExpandableListView.getExpandableListAdapter().getGroupCount();
+ for (int i = 0; i < groupLength; i++) {
+ if (!mExpandableListView.isGroupExpanded(i)) {
+ mExpandableListView.expandGroup(i);
+ }
+ }
+ }
+ }
+
+ /**
+ * 收起所有组
+ */
+ public void collapseAllGroup() {
+ if (mExpandableListView != null) {
+ int groupLength = mExpandableListView.getExpandableListAdapter().getGroupCount();
+ for (int i = 0; i < groupLength; i++) {
+ if (mExpandableListView.isGroupExpanded(i)) {
+ mExpandableListView.collapseGroup(i);
+ }
+ }
+ }
+ }
+
+ /**
+ * 清空展开状态
+ *
+ * @return
+ */
+ public void clearExpandStatus() {
+ collapseAllGroup();
+ }
+
+
+ public ExpandableListAdapter getAdapter() {
+ return mAdapter;
+ }
+
+ public ExpandableListView getExpandableListView() {
+ return mExpandableListView;
+ }
+
+}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUIListPopup.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUIListPopup.java
index 868d1e50..04da093d 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUIListPopup.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUIListPopup.java
@@ -5,8 +5,8 @@
import android.graphics.drawable.Drawable;
import android.webkit.WebView;
import android.widget.AdapterView;
-import android.widget.BaseAdapter;
import android.widget.FrameLayout;
+import android.widget.ListAdapter;
import android.widget.ListView;
import com.xuexiang.xui.R;
@@ -23,21 +23,21 @@
*/
public class XUIListPopup extends XUIPopup {
protected ListView mListView;
- protected BaseAdapter mAdapter;
+ protected ListAdapter mAdapter;
private boolean mHasDivider;
/**
- * Constructor.
+ * 构造方法.
*
* @param context Context
* @param direction
*/
- public XUIListPopup(Context context, int direction, BaseAdapter adapter) {
+ public XUIListPopup(Context context, int direction, ListAdapter adapter) {
super(context, direction);
mAdapter = adapter;
}
- public XUIListPopup(Context context, BaseAdapter adapter) {
+ public XUIListPopup(Context context, ListAdapter adapter) {
super(context);
mAdapter = adapter;
}
@@ -129,7 +129,9 @@ private void updateListViewDivider(ListView listView) {
* @return
*/
public T setDivider(Drawable divider) {
- mListView.setDivider(divider);
+ if (mListView != null) {
+ mListView.setDivider(divider);
+ }
return (T) this;
}
@@ -140,12 +142,17 @@ public T setDivider(Drawable divider) {
* @return
*/
public T setDividerHeight(int dividerHeight) {
- mListView.setDividerHeight(dividerHeight);
+ if (mListView != null) {
+ mListView.setDividerHeight(dividerHeight);
+ }
return (T) this;
}
- public BaseAdapter getAdapter() {
+ public ListAdapter getAdapter() {
return mAdapter;
}
+ public ListView getListView() {
+ return mListView;
+ }
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUIPopup.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUIPopup.java
index b30201e6..701c2fee 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUIPopup.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUIPopup.java
@@ -9,6 +9,9 @@
import android.widget.ImageView;
import com.xuexiang.xui.R;
+import com.xuexiang.xui.UIConsts;
+import com.xuexiang.xui.XUI;
+import com.xuexiang.xui.utils.ResUtils;
/**
* 提供一个浮层,支持自定义浮层的内容,支持在指定 {@link View} 的任一方向旁边展示该浮层,支持自定义浮层出现/消失的动画。
@@ -38,7 +41,6 @@ public class XUIPopup extends XUIBasePopup {
private int mPreferredDirection;
protected int mDirection;
-
protected int mX = -1;
protected int mY = -1;
protected int mArrowCenter;
@@ -169,6 +171,8 @@ private void calculatePosition(View attachedView) {
// 默认Y值与attachedView的Y值相同
mY = attachedViewLocation[1];
break;
+ default:
+ break;
}
} else {
mX = (mScreenSize.x - mWindowWidth) / 2;
@@ -277,4 +281,46 @@ public ViewGroup.LayoutParams generateLayoutParam(int width, int height) {
return new FrameLayout.LayoutParams(width, height);
}
+ /**
+ * 向下显示
+ *
+ * @param v
+ */
+ public void showDown(View v) {
+ setPreferredDirection(XUIPopup.DIRECTION_BOTTOM);
+ show(v);
+ }
+
+ /**
+ * 向上显示
+ *
+ * @param v
+ */
+ public void showUp(View v) {
+ setPreferredDirection(XUIPopup.DIRECTION_TOP);
+ show(v);
+ }
+
+ /**
+ * @return 获取弹出窗的宽度
+ */
+ protected int getPopupWidth() {
+ int width;
+ switch (XUI.getScreenType()) {
+ case UIConsts.ScreenType.BIG_TABLET:
+ width = ResUtils.getDimensionPixelSize(R.dimen.xui_popup_width_tablet_big);
+ break;
+ case UIConsts.ScreenType.SMALL_TABLET:
+ width = ResUtils.getDimensionPixelSize(R.dimen.xui_popup_width_tablet_small);
+ break;
+ case UIConsts.ScreenType.PHONE:
+ width = ResUtils.getDimensionPixelSize(R.dimen.xui_popup_width_phone);
+ break;
+ default:
+ width = ResUtils.getDimensionPixelSize(R.dimen.xui_popup_width_tablet_small);
+ break;
+ }
+ return width;
+ }
+
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUISimpleExpandablePopup.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUISimpleExpandablePopup.java
new file mode 100644
index 00000000..28394efe
--- /dev/null
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUISimpleExpandablePopup.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xui.widget.popupwindow.popup;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.widget.ExpandableListView;
+
+import com.xuexiang.xui.adapter.simple.ExpandableItem;
+import com.xuexiang.xui.adapter.simple.XUISimpleExpandableListAdapter;
+
+import java.util.List;
+
+/**
+ * 简单的可伸缩弹窗
+ *
+ * @author xuexiang
+ * @since 2019-11-11 16:31
+ */
+public class XUISimpleExpandablePopup extends XUIExpandableListPopup {
+
+ public XUISimpleExpandablePopup(Context context, List data) {
+ this(context, new XUISimpleExpandableListAdapter(data));
+ }
+
+ public XUISimpleExpandablePopup(Context context, ExpandableItem... data) {
+ this(context, new XUISimpleExpandableListAdapter(data));
+ }
+
+ public XUISimpleExpandablePopup(Context context, XUISimpleExpandableListAdapter adapter) {
+ super(context, adapter);
+ }
+
+ /**
+ * 创建弹窗
+ *
+ * @param onExpandableItemClickListener
+ * @return
+ */
+ public T create(int width, final OnExpandableItemClickListener onExpandableItemClickListener) {
+ create(width);
+ setOnExpandableItemClickListener(onExpandableItemClickListener);
+ return (T) this;
+ }
+
+ /**
+ * 创建弹窗
+ *
+ * @param width 弹窗的宽度
+ * @param maxHeight 弹窗最大的高度
+ * @return
+ */
+ @Override
+ public T create(int width, int maxHeight) {
+ super.create(width, maxHeight);
+ return (T) this;
+ }
+
+ /**
+ * 创建弹窗
+ *
+ * @param width
+ * @param maxHeight
+ * @param onExpandableItemClickListener
+ * @return
+ */
+ public T create(int width, int maxHeight, final OnExpandableItemClickListener onExpandableItemClickListener) {
+ create(width, maxHeight);
+ setOnExpandableItemClickListener(onExpandableItemClickListener);
+ return (T) this;
+ }
+
+ /**
+ * 设置条目点击监听
+ *
+ * @param onExpandableItemClickListener
+ * @return
+ */
+ public XUIExpandableListPopup setOnExpandableItemClickListener(final OnExpandableItemClickListener onExpandableItemClickListener) {
+ setOnExpandableItemClickListener(true, onExpandableItemClickListener);
+ return (T) this;
+ }
+
+ /**
+ * 设置条目点击监听
+ *
+ * @param autoDismiss
+ * @param onExpandableItemClickListener
+ * @return
+ */
+ public T setOnExpandableItemClickListener(final boolean autoDismiss, final OnExpandableItemClickListener onExpandableItemClickListener) {
+ if (mExpandableListView != null) {
+ mExpandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
+ @Override
+ public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
+ if (onExpandableItemClickListener != null) {
+ onExpandableItemClickListener.onExpandableItemClick(getAdapter(), getAdapter().getGroup(groupPosition), groupPosition, childPosition);
+ }
+ if (autoDismiss) {
+ dismiss();
+ }
+ return false;
+ }
+ });
+ }
+ return (T) this;
+ }
+
+ @Override
+ public XUISimpleExpandableListAdapter getAdapter() {
+ return (XUISimpleExpandableListAdapter) mAdapter;
+ }
+
+ @Override
+ public T create(int width) {
+ super.create(width);
+ return (T) this;
+ }
+
+ @Override
+ public T setDividerHeight(int dividerHeight) {
+ super.setDividerHeight(dividerHeight);
+ return (T) this;
+ }
+
+ @Override
+ public T setHasDivider(boolean hasDivider) {
+ super.setHasDivider(hasDivider);
+ return (T) this;
+ }
+
+ @Override
+ public T setGroupDivider(Drawable divider) {
+ super.setGroupDivider(divider);
+ return (T) this;
+ }
+
+ @Override
+ public T setChildDivider(Drawable divider) {
+ super.setChildDivider(divider);
+ return (T) this;
+ }
+
+ @Override
+ public T setEnableOnlyExpandOne(boolean enable) {
+ super.setEnableOnlyExpandOne(enable);
+ return (T) this;
+ }
+
+ /**
+ * 可伸缩列表条目点击监听
+ */
+ public interface OnExpandableItemClickListener {
+ /**
+ * 条目点击
+ *
+ * @param adapter
+ * @param group
+ * @param groupPosition 父节点索引
+ * @param childPosition 子节点索引
+ */
+ void onExpandableItemClick(XUISimpleExpandableListAdapter adapter, ExpandableItem group, int groupPosition, int childPosition);
+ }
+
+
+}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUISimplePopup.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUISimplePopup.java
index f2f067ba..9c75c8ce 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUISimplePopup.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/popupwindow/popup/XUISimplePopup.java
@@ -107,26 +107,6 @@ public void onItemClick(AdapterView> adapterView, View view, int position, lon
return (T) this;
}
- /**
- * 向下显示
- *
- * @param v
- */
- public void showDown(View v) {
- setPreferredDirection(XUIPopup.DIRECTION_BOTTOM);
- show(v);
- }
-
- /**
- * 向上显示
- *
- * @param v
- */
- public void showUp(View v) {
- setPreferredDirection(XUIPopup.DIRECTION_TOP);
- show(v);
- }
-
/**
* 条目点击监听
*/
@@ -146,24 +126,6 @@ public XUISimpleAdapter getAdapter() {
return (XUISimpleAdapter) mAdapter;
}
- private int getPopupWidth() {
- int width;
- switch (XUI.getScreenType()) {
- case UIConsts.ScreenType.BIG_TABLET:
- width = ResUtils.getDimensionPixelSize(R.dimen.xui_popup_width_tablet_big);
- break;
- case UIConsts.ScreenType.SMALL_TABLET:
- width = ResUtils.getDimensionPixelSize(R.dimen.xui_popup_width_tablet_small);
- break;
- case UIConsts.ScreenType.PHONE:
- width = ResUtils.getDimensionPixelSize(R.dimen.xui_popup_width_phone);
- break;
- default:
- width = ResUtils.getDimensionPixelSize(R.dimen.xui_popup_width_tablet_small);
- break;
- }
- return width;
- }
@Override
public T setHasDivider(boolean hasDivider) {
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/spinner/DropDownMenu.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/spinner/DropDownMenu.java
new file mode 100644
index 00000000..ca48c63b
--- /dev/null
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/spinner/DropDownMenu.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.xuexiang.xui.widget.spinner;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import com.xuexiang.xui.R;
+import com.xuexiang.xui.utils.DensityUtils;
+import com.xuexiang.xui.utils.DeviceUtils;
+import com.xuexiang.xui.utils.ResUtils;
+import com.xuexiang.xui.utils.ThemeUtils;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+
+/**
+ * 下拉选择菜单
+ *
+ * @author xuexiang
+ * @since 2019-11-28 12:26
+ */
+public class DropDownMenu extends LinearLayout {
+ /**
+ * 顶部菜单布局
+ */
+ private LinearLayout mTabMenuView;
+ /**
+ * 底部容器,包含popupMenuViews,maskView
+ */
+ private FrameLayout mContainerView;
+ /**
+ * 弹出菜单父布局
+ */
+ private FrameLayout mPopupMenuViews;
+ /**
+ * 遮罩半透明View,点击可关闭DropDownMenu
+ */
+ private View mMaskView;
+ /**
+ * tabMenuView里面选中的tab位置,-1表示未选中
+ */
+ private int mCurrentTabPosition = -1;
+
+ private int mContentLayoutId;
+ private View mContentView;
+ /**
+ * 分割线颜色
+ */
+ private int mDividerColor;
+ /**
+ * 分割线宽度
+ */
+ private int mDividerWidth;
+ /**
+ * 分割线的Margin
+ */
+ private int mDividerMargin;
+ /**
+ * tab选中颜色
+ */
+ private int mMenuTextSelectedColor;
+ /**
+ * tab未选中颜色
+ */
+ private int mMenuTextUnselectedColor;
+ /**
+ * tab字体水平padding
+ */
+ private int mMenuTextPaddingHorizontal;
+ /**
+ * tab字体水平padding
+ */
+ private int mMenuTextPaddingVertical;
+ /**
+ * 遮罩颜色
+ */
+ private int mMaskColor;
+ /**
+ * tab字体大小
+ */
+ private int mMenuTextSize;
+ /**
+ * tab选中图标
+ */
+ private Drawable mMenuSelectedIcon;
+ /**
+ * tab未选中图标
+ */
+ private Drawable mMenuUnselectedIcon;
+ /**
+ * 选择菜单的高度/屏幕高度 占比
+ */
+ private float mMenuHeightPercent = 0.5F;
+
+ public DropDownMenu(Context context) {
+ super(context, null);
+ }
+
+ public DropDownMenu(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.DropDownMenuStyle);
+ }
+
+ public DropDownMenu(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setOrientation(VERTICAL);
+ //为DropDownMenu添加自定义属性
+ TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DropDownMenu);
+ mContentLayoutId = array.getResourceId(R.styleable.DropDownMenu_ddm_contentLayoutId, -1);
+ mDividerColor = array.getColor(R.styleable.DropDownMenu_ddm_dividerColor, ThemeUtils.resolveColor(getContext(), R.attr.xui_config_color_separator_dark));
+ mDividerWidth = array.getDimensionPixelSize(R.styleable.DropDownMenu_ddm_dividerWidth, ResUtils.getDimensionPixelSize(R.dimen.default_ddm_divider_width));
+ mDividerMargin = array.getDimensionPixelSize(R.styleable.DropDownMenu_ddm_dividerMargin, ResUtils.getDimensionPixelSize(R.dimen.default_ddm_divider_margin));
+ int underlineColor = array.getColor(R.styleable.DropDownMenu_ddm_underlineColor, ThemeUtils.resolveColor(getContext(), R.attr.xui_config_color_separator_light));
+ int underlineHeight = array.getDimensionPixelSize(R.styleable.DropDownMenu_ddm_underlineHeight, ResUtils.getDimensionPixelSize(R.dimen.default_ddm_underline_height));
+ int menuBackgroundColor = array.getColor(R.styleable.DropDownMenu_ddm_menuBackgroundColor, Color.WHITE);
+ mMaskColor = array.getColor(R.styleable.DropDownMenu_ddm_maskColor, ResUtils.getColor(R.color.default_ddm_mask_color));
+ mMenuTextSelectedColor = array.getColor(R.styleable.DropDownMenu_ddm_menuTextSelectedColor, ThemeUtils.resolveColor(getContext(), R.attr.colorAccent));
+ mMenuTextUnselectedColor = array.getColor(R.styleable.DropDownMenu_ddm_menuTextUnselectedColor, ThemeUtils.resolveColor(getContext(), R.attr.xui_config_color_content_text));
+ mMenuTextPaddingHorizontal = array.getDimensionPixelSize(R.styleable.DropDownMenu_ddm_menuTextPaddingHorizontal, ResUtils.getDimensionPixelSize(R.dimen.default_ddm_menu_text_padding_horizontal));
+ mMenuTextPaddingVertical = array.getDimensionPixelSize(R.styleable.DropDownMenu_ddm_menuTextPaddingVertical, ResUtils.getDimensionPixelSize(R.dimen.default_ddm_menu_text_padding_vertical));
+ mMenuTextSize = array.getDimensionPixelSize(R.styleable.DropDownMenu_ddm_menuTextSize, ResUtils.getDimensionPixelSize(R.dimen.default_ddm_menu_text_size));
+ mMenuUnselectedIcon = ResUtils.getDrawableAttrRes(getContext(), array, R.styleable.DropDownMenu_ddm_menuUnselectedIcon);
+ if (mMenuUnselectedIcon == null) {
+ mMenuUnselectedIcon = ResUtils.getVectorDrawable(getContext(), R.drawable.ddm_ic_arrow_down);
+ }
+ mMenuSelectedIcon = ResUtils.getDrawableAttrRes(getContext(), array, R.styleable.DropDownMenu_ddm_menuSelectedIcon);
+ if (mMenuSelectedIcon == null) {
+ mMenuSelectedIcon = ResUtils.getVectorDrawable(getContext(), R.drawable.ddm_ic_arrow_up);
+ }
+ mMenuHeightPercent = array.getFloat(R.styleable.DropDownMenu_ddm_menuHeightPercent, mMenuHeightPercent);
+ array.recycle();
+
+ //初始化tabMenuView并添加到tabMenuView
+ mTabMenuView = new LinearLayout(context);
+ LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ mTabMenuView.setOrientation(HORIZONTAL);
+ mTabMenuView.setBackgroundColor(menuBackgroundColor);
+ mTabMenuView.setLayoutParams(params);
+ addView(mTabMenuView, 0);
+
+ //为tabMenuView添加下划线
+ View underLine = new View(getContext());
+ underLine.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, underlineHeight));
+ underLine.setBackgroundColor(underlineColor);
+ addView(underLine, 1);
+
+ //初始化containerView并将其添加到DropDownMenu
+ mContainerView = new FrameLayout(context);
+ mContainerView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
+ addView(mContainerView, 2);
+
+ }
+
+ /**
+ * 初始化DropDownMenu
+ *
+ * @param tabTexts
+ * @param popupViews
+ */
+ public void setDropDownMenu(@NonNull String[] tabTexts, @NonNull List popupViews) {
+ setDropDownMenu(Arrays.asList(tabTexts), popupViews);
+ }
+
+ /**
+ * 初始化DropDownMenu
+ *
+ * @param tabTexts
+ * @param popupViews
+ */
+ public void setDropDownMenu(@NonNull List tabTexts, @NonNull List popupViews) {
+ if (mContentLayoutId == -1) {
+ throw new IllegalArgumentException("mContentLayoutId == -1, You need to set properties app:ddm_contentLayoutId");
+ }
+ setDropDownMenu(tabTexts, popupViews, View.inflate(getContext(), mContentLayoutId, null));
+ }
+
+ /**
+ * 初始化DropDownMenu
+ *
+ * @param tabTexts
+ * @param popupViews
+ * @param contentView
+ */
+ public void setDropDownMenu(@NonNull String[] tabTexts, @NonNull List popupViews, @NonNull View contentView) {
+ setDropDownMenu(Arrays.asList(tabTexts), popupViews, contentView);
+ }
+
+ /**
+ * 初始化DropDownMenu
+ *
+ * @param tabTexts
+ * @param popupViews
+ * @param contentView
+ */
+ public void setDropDownMenu(@NonNull List tabTexts, @NonNull List popupViews, @NonNull View contentView) {
+ if (tabTexts.size() != popupViews.size()) {
+ throw new IllegalArgumentException("params not match, tabTexts.size() should be equal popupViews.size()");
+ }
+
+ for (int i = 0; i < tabTexts.size(); i++) {
+ addTab(tabTexts, i);
+ }
+
+ mContentView = contentView;
+ mContainerView.addView(contentView, 0);
+
+ mMaskView = new View(getContext());
+ mMaskView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
+ mMaskView.setBackgroundColor(mMaskColor);
+ mMaskView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ closeMenu();
+ }
+ });
+ mContainerView.addView(mMaskView, 1);
+ mMaskView.setVisibility(GONE);
+ if (mContainerView.getChildAt(2) != null) {
+ mContainerView.removeViewAt(2);
+ }
+
+ mPopupMenuViews = new FrameLayout(getContext());
+ mPopupMenuViews.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) (DeviceUtils.getScreenSize(getContext()).y * mMenuHeightPercent)));
+ mPopupMenuViews.setVisibility(GONE);
+ mContainerView.addView(mPopupMenuViews, 2);
+
+ for (int i = 0; i < popupViews.size(); i++) {
+ popupViews.get(i).setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+ mPopupMenuViews.addView(popupViews.get(i), i);
+ }
+ }
+
+ private void addTab(@NonNull List tabTexts, int index) {
+ final TextView tab = new TextView(getContext());
+ tab.setSingleLine();
+ tab.setEllipsize(TextUtils.TruncateAt.END);
+ tab.setGravity(Gravity.CENTER);
+ tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
+ tab.setLayoutParams(new LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0F));
+ tab.setTextColor(mMenuTextUnselectedColor);
+ tab.setCompoundDrawablesWithIntrinsicBounds(null, null, mMenuUnselectedIcon, null);
+ tab.setText(tabTexts.get(index));
+ tab.setPadding(mMenuTextPaddingHorizontal, mMenuTextPaddingVertical, mMenuTextPaddingHorizontal, mMenuTextPaddingVertical);
+ //添加点击事件
+ tab.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ switchMenu(tab);
+ }
+ });
+ mTabMenuView.addView(tab);
+ //添加分割线
+ if (index < tabTexts.size() - 1) {
+ View view = new View(getContext());
+ LayoutParams params = new LayoutParams(mDividerWidth, ViewGroup.LayoutParams.MATCH_PARENT);
+ params.topMargin = mDividerMargin;
+ params.bottomMargin = mDividerMargin;
+ view.setLayoutParams(params);
+ view.setBackgroundColor(mDividerColor);
+ mTabMenuView.addView(view);
+ }
+ }
+
+ /**
+ * 设置tab菜单文字
+ *
+ * @param text
+ */
+ public void setTabMenuText(String text) {
+ if (mCurrentTabPosition != -1) {
+ ((TextView) mTabMenuView.getChildAt(mCurrentTabPosition)).setText(text);
+ }
+ }
+
+ /**
+ * 设置tab菜单是否可点击
+ *
+ * @param clickable
+ */
+ public void setTabMenuClickable(boolean clickable) {
+ for (int i = 0; i < mTabMenuView.getChildCount(); i = i + 2) {
+ mTabMenuView.getChildAt(i).setClickable(clickable);
+ }
+ }
+
+ /**
+ * 关闭菜单
+ */
+ public void closeMenu() {
+ if (mCurrentTabPosition != -1) {
+ ((TextView) mTabMenuView.getChildAt(mCurrentTabPosition)).setTextColor(mMenuTextUnselectedColor);
+ ((TextView) mTabMenuView.getChildAt(mCurrentTabPosition)).setCompoundDrawablesWithIntrinsicBounds(null, null, mMenuUnselectedIcon, null);
+ mPopupMenuViews.setVisibility(View.GONE);
+ mPopupMenuViews.setAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.ddm_menu_out));
+ mMaskView.setVisibility(GONE);
+ mMaskView.setAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.ddm_mask_out));
+ mCurrentTabPosition = -1;
+ }
+ }
+
+ /**
+ * DropDownMenu是否处于可见状态
+ *
+ * @return
+ */
+ public boolean isShowing() {
+ return mCurrentTabPosition != -1;
+ }
+
+ /**
+ * @return 内容页
+ */
+ public View getContentView() {
+ return mContentView;
+ }
+
+ /**
+ * 切换菜单
+ *
+ * @param target
+ */
+ private void switchMenu(View target) {
+ for (int i = 0; i < mTabMenuView.getChildCount(); i = i + 2) {
+ if (target == mTabMenuView.getChildAt(i)) {
+ if (mCurrentTabPosition == i) {
+ closeMenu();
+ } else {
+ if (mCurrentTabPosition == -1) {
+ mPopupMenuViews.setVisibility(View.VISIBLE);
+ mPopupMenuViews.setAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.ddm_menu_in));
+ mMaskView.setVisibility(VISIBLE);
+ mMaskView.setAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.ddm_mask_in));
+ mPopupMenuViews.getChildAt(i / 2).setVisibility(View.VISIBLE);
+ } else {
+ mPopupMenuViews.getChildAt(i / 2).setVisibility(View.VISIBLE);
+ }
+ mCurrentTabPosition = i;
+ ((TextView) mTabMenuView.getChildAt(i)).setTextColor(mMenuTextSelectedColor);
+ ((TextView) mTabMenuView.getChildAt(i)).setCompoundDrawablesWithIntrinsicBounds(null, null, mMenuSelectedIcon, null);
+ }
+ } else {
+ ((TextView) mTabMenuView.getChildAt(i)).setTextColor(mMenuTextUnselectedColor);
+ ((TextView) mTabMenuView.getChildAt(i)).setCompoundDrawablesWithIntrinsicBounds(null, null, mMenuUnselectedIcon, null);
+ mPopupMenuViews.getChildAt(i / 2).setVisibility(View.GONE);
+ }
+ }
+ }
+}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/spinner/editspinner/EditSpinnerAdapter.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/spinner/editspinner/EditSpinnerAdapter.java
index b74c52f9..8640d1c8 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/spinner/editspinner/EditSpinnerAdapter.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/spinner/editspinner/EditSpinnerAdapter.java
@@ -89,7 +89,7 @@ public View getView(int position, View convertView, ViewGroup parent) {
final TextView textView;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
- convertView = inflater.inflate(R.layout.ms_list_item, parent, false);
+ convertView = inflater.inflate(R.layout.ms_layout_list_item, parent, false);
textView = convertView.findViewById(R.id.tv_tinted_spinner);
textView.setTextColor(textColor);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/spinner/materialspinner/MaterialSpinnerBaseAdapter.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/spinner/materialspinner/MaterialSpinnerBaseAdapter.java
index 0c04b374..e16716fd 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/spinner/materialspinner/MaterialSpinnerBaseAdapter.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/spinner/materialspinner/MaterialSpinnerBaseAdapter.java
@@ -39,7 +39,7 @@ public View getView(int position, View convertView, ViewGroup parent) {
final TextView textView;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
- convertView = inflater.inflate(R.layout.ms_list_item, parent, false);
+ convertView = inflater.inflate(R.layout.ms_layout_list_item, parent, false);
textView = convertView.findViewById(R.id.tv_tinted_spinner);
textView.setTextColor(textColor);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/statelayout/MultipleStatusView.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/statelayout/MultipleStatusView.java
index d20b2c46..7cad6a98 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/statelayout/MultipleStatusView.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/statelayout/MultipleStatusView.java
@@ -99,10 +99,10 @@ public MultipleStatusView(Context context, AttributeSet attrs, int defStyleAttr)
private void initAttrs(Context context, AttributeSet attrs, int defStyleAttr) {
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultipleStatusView, defStyleAttr, 0);
- mEmptyViewResId = a.getResourceId(R.styleable.MultipleStatusView_msv_emptyView, R.layout.msv_empty_view);
- mErrorViewResId = a.getResourceId(R.styleable.MultipleStatusView_msv_errorView, R.layout.msv_error_view);
- mLoadingViewResId = a.getResourceId(R.styleable.MultipleStatusView_msv_loadingView, R.layout.msv_loading_view);
- mNoNetworkViewResId = a.getResourceId(R.styleable.MultipleStatusView_msv_noNetworkView, R.layout.msv_no_network_view);
+ mEmptyViewResId = a.getResourceId(R.styleable.MultipleStatusView_msv_emptyView, R.layout.msv_layout_empty_view);
+ mErrorViewResId = a.getResourceId(R.styleable.MultipleStatusView_msv_errorView, R.layout.msv_layout_error_view);
+ mLoadingViewResId = a.getResourceId(R.styleable.MultipleStatusView_msv_loadingView, R.layout.msv_layout_loading_view);
+ mNoNetworkViewResId = a.getResourceId(R.styleable.MultipleStatusView_msv_noNetworkView, R.layout.msv_layout_no_network_view);
mContentViewResId = a.getResourceId(R.styleable.MultipleStatusView_msv_contentView, NULL_RESOURCE_ID);
a.recycle();
mInflater = LayoutInflater.from(getContext());
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/MultiTabControlView.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/MultiTabControlView.java
index 4ccdb51a..473fd9a8 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/MultiTabControlView.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/MultiTabControlView.java
@@ -76,6 +76,14 @@ public class MultiTabControlView extends LinearLayout implements HasTypeface {
* 选项间距
*/
private int mItemPadding;
+ /**
+ * 选项水平间距
+ */
+ private int mItemPaddingHorizontal;
+ /**
+ * 选项垂直间距
+ */
+ private int mItemPaddingVertical;
/**
* 选中背景的颜色
*/
@@ -106,7 +114,6 @@ public class MultiTabControlView extends LinearLayout implements HasTypeface {
private boolean mEqualWidth = false;
private ColorStateList mTextColorStateList;
- //Item organization
private LinkedHashMap mItemMap = new LinkedHashMap<>();
private List mOptions;
@@ -117,19 +124,21 @@ public class MultiTabControlView extends LinearLayout implements HasTypeface {
*/
private void addOnCheckedChangeListener(CheckBox cb) {
if (cb != null) {
- cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton checkBox, boolean b) {
- if (mListener != null) {
- String identifier = checkBox.getText().toString();
- String value = mItemMap.get(identifier);
- mListener.newSelection(identifier, value, checkBox.isChecked());
- }
- }
- });
+ cb.setOnCheckedChangeListener(mCheckBoxListener);
}
}
+ private CompoundButton.OnCheckedChangeListener mCheckBoxListener = new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton checkBox, boolean isChecked) {
+ if (mListener != null) {
+ String identifier = checkBox.getText().toString();
+ String value = mItemMap.get(identifier);
+ mListener.newSelection(identifier, value, checkBox.isChecked());
+ }
+ }
+ };
+
public MultiTabControlView(Context context) {
super(context, null);
//Initialize
@@ -164,6 +173,8 @@ private void initAttrs(Context context, AttributeSet attrs) throws Exception {
mUnselectedTextColor = attributes.getColor(R.styleable.TabControlView_tcv_unselectedTextColor, ThemeUtils.resolveColor(context, R.attr.colorAccent));
mStrokeWidth = attributes.getDimensionPixelSize(R.styleable.TabControlView_tcv_strokeWidth, ResUtils.getDimensionPixelSize(R.dimen.default_tcv_stroke_width));
mItemPadding = attributes.getDimensionPixelSize(R.styleable.TabControlView_tcv_item_padding, -1);
+ mItemPaddingHorizontal = attributes.getDimensionPixelSize(R.styleable.TabControlView_tcv_item_padding_horizontal, -1);
+ mItemPaddingVertical = attributes.getDimensionPixelSize(R.styleable.TabControlView_tcv_item_padding_vertical, -1);
//Set text mSelectedColor state list
mTextColorStateList = new ColorStateList(new int[][]{
@@ -243,6 +254,9 @@ private void update() {
if (mItemPadding != -1) {
cb.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
}
+ if (mItemPaddingHorizontal != -1 && mItemPaddingVertical != -1) {
+ cb.setPadding(mItemPaddingHorizontal, mItemPaddingVertical, mItemPaddingHorizontal, mItemPaddingVertical);
+ }
cb.setMinWidth(mStrokeWidth * 10);
cb.setGravity(Gravity.CENTER);
cb.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
@@ -443,20 +457,65 @@ public MultiTabControlView setSelection(String... values) {
* @param value
*/
public MultiTabControlView setSelection(String value) {
- String buttonText = "";
- if (mItemMap.containsValue(value)) {
- for (String entry : mItemMap.keySet()) {
- if (mItemMap.get(entry).equalsIgnoreCase(value)) {
- buttonText = entry;
+ setSelectionStatus(value, true);
+ return this;
+ }
+
+ /**
+ * 通过值 设置tab的选中状态
+ *
+ * @param value
+ */
+ public MultiTabControlView setSelectionStatus(String value, boolean isChecked) {
+ String title = getTitleByValue(value);
+ setSelectionStatusByTitle(title, isChecked);
+ return this;
+ }
+
+ /**
+ * 静默通过标题设置tab的选中状态
+ *
+ * @param title
+ * @param isChecked
+ * @return
+ */
+ public MultiTabControlView setSelectionStatusByTitle(String title, boolean isChecked) {
+ setSelectionStatusByTitle(title, isChecked, true);
+ return this;
+ }
+
+ /**
+ * 通过标题设置tab的选中状态
+ *
+ * @param title
+ * @param isChecked 是否选中
+ * @param isSilent 是否静默设置
+ * @return
+ */
+ public MultiTabControlView setSelectionStatusByTitle(String title, boolean isChecked, boolean isSilent) {
+ for (CheckBox option : mOptions) {
+ if (option.getText().toString().equalsIgnoreCase(title)) {
+ if (isSilent) {
+ option.setOnCheckedChangeListener(null);
+ option.setChecked(isChecked);
+ addOnCheckedChangeListener(option);
+ } else {
+ option.setChecked(isChecked);
}
}
}
- for (CheckBox option : mOptions) {
- if (option.getText().toString().equalsIgnoreCase(buttonText)) {
- option.setChecked(true);
+ return this;
+ }
+
+ private String getTitleByValue(String value) {
+ if (mItemMap.containsValue(value)) {
+ for (String key : mItemMap.keySet()) {
+ if (mItemMap.get(key).equalsIgnoreCase(value)) {
+ return key;
+ }
}
}
- return this;
+ return "";
}
/**
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/TabControlView.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/TabControlView.java
index 50d19157..b1b30901 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/TabControlView.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/TabControlView.java
@@ -73,6 +73,14 @@ public class TabControlView extends RadioGroup implements HasTypeface {
* 选项间距
*/
private int mItemPadding;
+ /**
+ * 选项水平间距
+ */
+ private int mItemPaddingHorizontal;
+ /**
+ * 选项垂直间距
+ */
+ private int mItemPaddingVertical;
/**
* 选中背景的颜色
*/
@@ -104,6 +112,7 @@ public class TabControlView extends RadioGroup implements HasTypeface {
private ColorStateList mTextColorStateList;
//Item organization
+
private LinkedHashMap mItemMap = new LinkedHashMap<>();
private List mOptions;
/**
@@ -155,6 +164,8 @@ private void initAttrs(Context context, AttributeSet attrs) throws Exception {
mUnselectedTextColor = attributes.getColor(R.styleable.TabControlView_tcv_unselectedTextColor, ThemeUtils.resolveColor(context, R.attr.colorAccent));
mStrokeWidth = attributes.getDimensionPixelSize(R.styleable.TabControlView_tcv_strokeWidth, ResUtils.getDimensionPixelSize(R.dimen.default_tcv_stroke_width));
mItemPadding = attributes.getDimensionPixelSize(R.styleable.TabControlView_tcv_item_padding, -1);
+ mItemPaddingHorizontal = attributes.getDimensionPixelSize(R.styleable.TabControlView_tcv_item_padding_horizontal, -1);
+ mItemPaddingVertical = attributes.getDimensionPixelSize(R.styleable.TabControlView_tcv_item_padding_vertical, -1);
//Set text mSelectedColor state list
mTextColorStateList = new ColorStateList(new int[][]{
@@ -232,6 +243,9 @@ private void update() {
if (mItemPadding != -1) {
rb.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
}
+ if (mItemPaddingHorizontal != -1 && mItemPaddingVertical != -1) {
+ rb.setPadding(mItemPaddingHorizontal, mItemPaddingVertical, mItemPaddingHorizontal, mItemPaddingVertical);
+ }
rb.setMinWidth(mStrokeWidth * 10);
rb.setGravity(Gravity.CENTER);
rb.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
@@ -346,6 +360,12 @@ public TabControlView setItems(String[] itemArray, String[] valueArray) throws E
return this;
}
+ /**
+ * 为每一个选项设置 items and values
+ *
+ * @param itemArray
+ * @param valueArray
+ */
private void setItems(CharSequence[] itemArray, CharSequence[] valueArray) throws Exception {
if (itemArray != null && valueArray != null) {
if (itemArray.length != valueArray.length) {
@@ -404,22 +424,64 @@ public TabControlView setDefaultSelection(int defaultSelection) throws Exception
* @param value
*/
public TabControlView setSelection(String value) {
- String buttonText = "";
- if (mItemMap.containsValue(value)) {
- for (String entry : mItemMap.keySet()) {
- if (mItemMap.get(entry).equalsIgnoreCase(value)) {
- buttonText = entry;
- }
- }
- }
+ setSelection(value, true);
+ return this;
+ }
+
+ /**
+ * 通过值 设置选中的Tab
+ *
+ * @param value
+ */
+ public TabControlView setSelection(String value, boolean isSilent) {
+ String title = getTitleByValue(value);
+ setSelectionTitle(title, isSilent);
+ return this;
+ }
+
+ /**
+ * 通过标题设置选中的Tab
+ *
+ * @param title
+ * @return
+ */
+ public TabControlView setSelectionTitle(String title) {
+ setSelectionTitle(title, true);
+ return this;
+ }
+
+ /**
+ * 通过标题设置选中的Tab
+ *
+ * @param title
+ * @param isSilent 是否静默设置
+ * @return
+ */
+ public TabControlView setSelectionTitle(String title, boolean isSilent) {
for (RadioButton option : mOptions) {
- if (option.getText().toString().equalsIgnoreCase(buttonText)) {
- this.check(option.getId());
+ if (option.getText().toString().equalsIgnoreCase(title)) {
+ if (isSilent) {
+ setOnCheckedChangeListener(null);
+ this.check(option.getId());
+ setOnCheckedChangeListener(mSelectionChangedListener);
+ } else {
+ this.check(option.getId());
+ }
}
}
return this;
}
+ private String getTitleByValue(String value) {
+ if (mItemMap.containsValue(value)) {
+ for (String key : mItemMap.keySet()) {
+ if (mItemMap.get(key).equalsIgnoreCase(value)) {
+ return key;
+ }
+ }
+ }
+ return "";
+ }
/**
* Sets the colors used when drawing the view. The primary color will be used for selected color
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/ExpandableTextView.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/ExpandableTextView.java
index bd9eae14..e35c95b1 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/ExpandableTextView.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/ExpandableTextView.java
@@ -93,8 +93,8 @@ public ExpandableTextView(Context context, AttributeSet attrs, int defStyle) {
}
@Override
- public void setOrientation(int orientation){
- if(LinearLayout.HORIZONTAL == orientation){
+ public void setOrientation(int orientation) {
+ if (LinearLayout.HORIZONTAL == orientation) {
throw new IllegalArgumentException("ExpandableTextView only supports Vertical Orientation.");
}
super.setOrientation(orientation);
@@ -130,6 +130,7 @@ public void onClick(View view) {
public void onAnimationStart(Animation animation) {
applyAlphaAnimation(mTv, mAnimAlphaStart);
}
+
@Override
public void onAnimationEnd(Animation animation) {
// clear animation here to avoid repeated applyTransformation() calls
@@ -142,8 +143,10 @@ public void onAnimationEnd(Animation animation) {
mListener.onExpandStateChanged(mTv, !mCollapsed);
}
}
+
@Override
- public void onAnimationRepeat(Animation animation) { }
+ public void onAnimationRepeat(Animation animation) {
+ }
});
clearAnimation();
@@ -213,6 +216,7 @@ public void run() {
/**
* 设置伸展状态监听
+ *
* @param listener
*/
public void setOnExpandStateChangeListener(@Nullable OnExpandStateChangeListener listener) {
@@ -336,7 +340,7 @@ public ExpandCollapseAnimation(View view, int startHeight, int endHeight) {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
- final int newHeight = (int)((mEndHeight - mStartHeight) * interpolatedTime + mStartHeight);
+ final int newHeight = (int) ((mEndHeight - mStartHeight) * interpolatedTime + mStartHeight);
mTv.setMaxHeight(newHeight - mMarginBetweenTxtAndBottom);
if (Float.compare(mAnimAlphaStart, 1.0f) != 0) {
applyAlphaAnimation(mTv, mAnimAlphaStart + interpolatedTime * (1.0f - mAnimAlphaStart));
@@ -346,12 +350,12 @@ protected void applyTransformation(float interpolatedTime, Transformation t) {
}
@Override
- public void initialize( int width, int height, int parentWidth, int parentHeight ) {
+ public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
@Override
- public boolean willChangeBounds( ) {
+ public boolean willChangeBounds() {
return true;
}
}
@@ -360,7 +364,7 @@ public interface OnExpandStateChangeListener {
/**
* Called when the expand/collapse animation has been finished
*
- * @param textView - TextView being expanded/collapsed
+ * @param textView - TextView being expanded/collapsed
* @param isExpanded - true if the TextView has been expanded
*/
void onExpandStateChanged(TextView textView, boolean isExpanded);
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/MarqueeTextView.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/MarqueeTextView.java
index fce6869c..4e221e3d 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/MarqueeTextView.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/MarqueeTextView.java
@@ -246,7 +246,8 @@ public boolean removeDisplayString(String displayString) {
public boolean removeDisplayEntity(DisplayEntity displayEntity) {
if (displayEntity != null && displayEntity.isValid()) {
if (isRollingDisplayEntity(displayEntity)) {
- if (mCurrentIndex <= mDisplayList.size() - 1) { //防止remove出错
+ //防止remove出错
+ if (mCurrentIndex <= mDisplayList.size() - 1) {
mDisplayList.remove(mCurrentIndex);
rollDisplayByIndex(mCurrentIndex);
return true;
@@ -314,11 +315,13 @@ private void updateDisplayText(DisplayEntity displayEntity) {
if (displayEntity != null) {
if (mOnMarqueeListener != null) {
DisplayEntity temp = mOnMarqueeListener.onStartMarquee(displayEntity, mCurrentIndex);
- if (temp != null && temp.isValid()) { //返回的消息有效
+ //返回的消息有效
+ if (temp != null && temp.isValid()) {
displayEntity = temp;
mDisplayList.set(mCurrentIndex, displayEntity);
} else { //返回的消息无效, 去除该条消息,继续滚动下一条
- if (mCurrentIndex <= mDisplayList.size() - 1) { //防止remove出错
+ //防止remove出错
+ if (mCurrentIndex <= mDisplayList.size() - 1) {
mDisplayList.remove(mCurrentIndex);
}
rollDisplayByIndex(mCurrentIndex);
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/marqueen/MarqueeFactory.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/marqueen/MarqueeFactory.java
index 966b9b03..9cc6d26a 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/marqueen/MarqueeFactory.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/marqueen/MarqueeFactory.java
@@ -45,6 +45,7 @@ public void setData(List datas) {
/**
* 设置Item的监听
+ *
* @param onItemClickListener
*/
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
@@ -59,13 +60,13 @@ public List getMarqueeViews() {
private void registerOnItemClick() {
if (!isOnItemClickRegistered && mOnItemClickListener != null && mDatas != null) {
for (int i = 0; i < mDatas.size(); i++) {
- T mView = mViews.get(i);
+ T view = mViews.get(i);
E data = mDatas.get(i);
- mView.setTag(new ViewHolder(mView, data, i));
- mView.setOnClickListener(new View.OnClickListener() {
+ final ViewHolder viewHolder = new ViewHolder<>(view, data, i);
+ view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- mOnItemClickListener.onItemClickListener((ViewHolder) view.getTag());
+ mOnItemClickListener.onItemClick(view, viewHolder);
}
});
}
@@ -73,8 +74,20 @@ public void onClick(View view) {
}
}
+ /**
+ * 条目点击监听
+ *
+ * @param
+ * @param
+ */
public interface OnItemClickListener {
- void onItemClickListener(ViewHolder holder);
+ /**
+ * 条目点击
+ *
+ * @param view
+ * @param holder
+ */
+ void onItemClick(View view, ViewHolder holder);
}
public static class ViewHolder {
@@ -117,6 +130,6 @@ public ViewHolder setPosition(int position) {
}
public void setAttachedToMarqueeView(MarqueeView marqueeView) {
- mMarqueeView = marqueeView;
+ mMarqueeView = marqueeView;
}
}
\ No newline at end of file
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/supertextview/SuperTextView.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/supertextview/SuperTextView.java
index d8c4d9c6..99d23b78 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/supertextview/SuperTextView.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/supertextview/SuperTextView.java
@@ -1,6 +1,7 @@
package com.xuexiang.xui.widget.textview.supertextview;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
@@ -48,22 +49,58 @@ public class SuperTextView extends RelativeLayout implements HasTypeface {
private ImageView mLeftIconIV, mRightIconIV;
private LayoutParams mLeftImgParams, mRightImgParams;
- private int mLeftIconWidth;//左边图标的宽
- private int mLeftIconHeight;//左边图标的高
-
- private int mRightIconWidth;//右边图标的宽
- private int mRightIconHeight;//右边图标的高
-
- private int mLeftIconMarginLeft;//左边图标的左边距
- private int mRightIconMarginRight;//右边图标的右边距
-
- private Drawable mLeftIconRes;//左边图标资源
- private Drawable mRightIconRes;//右边图标资源
-
- private int mDefaultTextColor;//文字默认颜色
- private int mDefaultTextSize;//默认字体大小
- private int mDefaultMaxEms; //默认文字的最大字符数
- private int mDefaultMargin; //默认间距
+ /**
+ * 左边图标资源
+ */
+ private Drawable mLeftIconRes;
+ /**
+ * 左边图标的宽
+ */
+ private int mLeftIconWidth;
+ /**
+ * 左边图标的高
+ */
+ private int mLeftIconHeight;
+ /**
+ * 左边图标的左边距
+ */
+ private int mLeftIconMarginLeft;
+ private ColorStateList mLeftIconTint;
+ private int mLeftIconPadding;
+ /**
+ * 右边图标资源
+ */
+ private Drawable mRightIconRes;
+ /**
+ * 右边图标的宽
+ */
+ private int mRightIconWidth;
+ /**
+ * 右边图标的高
+ */
+ private int mRightIconHeight;
+ /**
+ * 右边图标的右边距
+ */
+ private int mRightIconMarginRight;
+ private ColorStateList mRightIconTint;
+ private int mRightIconPadding;
+ /**
+ * 文字默认颜色
+ */
+ private int mDefaultTextColor;
+ /**
+ * 默认字体大小
+ */
+ private int mDefaultTextSize;
+ /**
+ * 默认文字的最大字符数
+ */
+ private int mDefaultMaxEms;
+ /**
+ * 默认间距
+ */
+ private int mDefaultMargin;
private String mLeftTextString;
private String mLeftTopTextString;
@@ -89,7 +126,6 @@ public class SuperTextView extends RelativeLayout implements HasTypeface {
private int mRightTopTextColor;
private int mRightBottomTextColor;
-
private int mLeftTextSize;
private int mLeftTopTextSize;
private int mLeftBottomTextSize;
@@ -165,14 +201,12 @@ public class SuperTextView extends RelativeLayout implements HasTypeface {
private static final int GRAVITY_LEFT_CENTER = 0;
private static final int GRAVITY_CENTER = 1;
private static final int GRAVITY_RIGHT_CENTER = 2;
-
private static final int DEFAULT_GRAVITY = 1;
private int mLeftGravity;
private int mCenterGravity;
private int mRightGravity;
-
private int mLeftViewWidth;
private View mTopDividerLineView, mBottomDividerLineView;
@@ -233,65 +267,84 @@ public class SuperTextView extends RelativeLayout implements HasTypeface {
private OnRightImageViewClickListener mRightImageViewClickListener;
private boolean mEnableEdit = false;
- //输入框
+ /**
+ * 输入框
+ */
private EditText mCenterEditText;
- //输入框布局参数
- private LayoutParams mCenterEditTextParams;
private int mEditTextWidth = LayoutParams.MATCH_PARENT;
- //输入框的背景
+ private static final int TYPE_NONE = 0;
+ private static final int TYPE_CLEAR = 1;
+ private static final int TYPE_PASSWORD = 2;
+ /**
+ * 编辑输入框类型
+ */
+ private int mEditTextButtonType = TYPE_CLEAR;
+ /**
+ * 输入框的背景
+ */
private Drawable mEditBackground;
private String mEditTextHint;
private String mEditTextString;
private int mEditTextInputType;
- //密码输入框文字的样式是否是“*”
+ /**
+ * 密码输入框文字的样式是否是“*”
+ */
private boolean mIsAsteriskStyle;
- private static final int TYPE_NONE = 0;
- private static final int TYPE_CLEAR = 1;
- private static final int TYPE_PASSWORD = 2;
- private int mEditTextButtonType = TYPE_CLEAR;
-
private static final int TYPE_CHECKBOX = 0;
private static final int TYPE_SWITCH = 1;
private int mRightViewType;
-
- //右边checkbox
+ /**
+ * 右边checkbox
+ */
private CheckBox mRightCheckBox;
- //右边checkbox
- private LayoutParams mRightCheckBoxParams;
- //checkBox的背景
+ /**
+ * checkBox的背景
+ */
private Drawable mRightCheckBoxBg;
- //右边checkBox的右边距
+ /**
+ * 右边checkBox的右边距
+ */
private int mRightCheckBoxMarginRight;
- //是否默认选中
+ /**
+ * 是否默认选中
+ */
private boolean mIsChecked;
-
- //中间空间的高度
+ /**
+ * 中间空间的高度
+ */
private int mCenterSpaceHeight;
- //右边switch
+ /**
+ * 右边switch
+ */
private Switch mRightSwitch;
- private LayoutParams mRightSwitchParams;
private int mRightSwitchMarginRight;
private boolean mSwitchIsChecked;
- //Switch开关关闭的文字提示
+ /**
+ * Switch开关关闭的文字提示
+ */
private String mSwitchTextOff;
- //Switch开关打开的文字提示
+ /**
+ * Switch开关打开的文字提示
+ */
private String mSwitchTextOn;
-
private int mSwitchMinWidth;
private int mSwitchPadding;
-
private int mThumbTextPadding;
-
- //Switch开关的滑块样式
+ /**
+ * Switch开关的滑块样式
+ */
private Drawable mSwitchThumbResource;
- //Switch开关的底层样式
+ /**
+ * Switch开关的底层样式
+ */
private Drawable mSwitchTrackResource;
- /////////////////////一下是shape相关属性
+ //====================一下是shape相关属性==================//
+
private int mDefaultShapeColor;
private int mSelectorPressedColor;
@@ -464,17 +517,19 @@ private void getAttr(AttributeSet attrs) {
mRightViewMarginLeft = typedArray.getDimensionPixelSize(R.styleable.SuperTextView_sRightViewMarginLeft, mDefaultMargin);
mRightViewMarginRight = typedArray.getDimensionPixelSize(R.styleable.SuperTextView_sRightViewMarginRight, mDefaultMargin);
///////////////////////////////////////////////
+ mLeftIconRes = ResUtils.getDrawableAttrRes(getContext(), typedArray, R.styleable.SuperTextView_sLeftIconRes);
mLeftIconWidth = typedArray.getDimensionPixelSize(R.styleable.SuperTextView_sLeftIconWidth, 0);
mLeftIconHeight = typedArray.getDimensionPixelSize(R.styleable.SuperTextView_sLeftIconHeight, 0);
+ mLeftIconMarginLeft = typedArray.getDimensionPixelSize(R.styleable.SuperTextView_sLeftIconMarginLeft, mDefaultMargin);
+ mLeftIconTint = typedArray.getColorStateList(R.styleable.SuperTextView_sLeftIconTint);
+ mLeftIconPadding = typedArray.getDimensionPixelSize(R.styleable.SuperTextView_sLeftIconPadding, 0);
+ mRightIconRes = ResUtils.getDrawableAttrRes(getContext(), typedArray, R.styleable.SuperTextView_sRightIconRes);
mRightIconWidth = typedArray.getDimensionPixelSize(R.styleable.SuperTextView_sRightIconWidth, 0);
mRightIconHeight = typedArray.getDimensionPixelSize(R.styleable.SuperTextView_sRightIconHeight, 0);
-
- mLeftIconMarginLeft = typedArray.getDimensionPixelSize(R.styleable.SuperTextView_sLeftIconMarginLeft, mDefaultMargin);
mRightIconMarginRight = typedArray.getDimensionPixelSize(R.styleable.SuperTextView_sRightIconMarginRight, mDefaultMargin);
-
- mLeftIconRes = ResUtils.getDrawableAttrRes(getContext(), typedArray, R.styleable.SuperTextView_sLeftIconRes);
- mRightIconRes = ResUtils.getDrawableAttrRes(getContext(), typedArray, R.styleable.SuperTextView_sRightIconRes);
+ mRightIconTint = typedArray.getColorStateList(R.styleable.SuperTextView_sLeftIconTint);
+ mRightIconPadding = typedArray.getDimensionPixelSize(R.styleable.SuperTextView_sLeftIconPadding, 0);
//////////////////////////////////////////////
mLeftTopTextBold = typedArray.getBoolean(R.styleable.SuperTextView_sLeftTopTextIsBold, false);
@@ -622,10 +677,16 @@ private void initLeftIcon() {
mLeftIconIV.setScaleType(ImageView.ScaleType.FIT_CENTER);
mLeftIconIV.setId(R.id.sLeftImgId);
mLeftIconIV.setLayoutParams(mLeftImgParams);
+ mLeftIconIV.setPadding(mLeftIconPadding, mLeftIconPadding, mLeftIconPadding, mLeftIconPadding);
if (mLeftIconRes != null) {
mLeftImgParams.setMargins(mLeftIconMarginLeft, 0, 0, 0);
mLeftIconIV.setImageDrawable(mLeftIconRes);
}
+ if (mLeftIconTint != null) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ mLeftIconIV.setImageTintList(mLeftIconTint);
+ }
+ }
addView(mLeftIconIV);
}
@@ -659,10 +720,16 @@ private void initRightIcon() {
mRightIconIV.setScaleType(ImageView.ScaleType.FIT_CENTER);
mRightIconIV.setId(R.id.sRightImgId);
mRightIconIV.setLayoutParams(mRightImgParams);
+ mRightIconIV.setPadding(mRightIconPadding, mRightIconPadding, mRightIconPadding, mRightIconPadding);
if (mRightIconRes != null) {
mRightImgParams.setMargins(0, 0, mRightIconMarginRight, 0);
mRightIconIV.setImageDrawable(mRightIconRes);
}
+ if (mRightIconTint != null) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ mRightIconIV.setImageTintList(mRightIconTint);
+ }
+ }
addView(mRightIconIV);
}
@@ -712,7 +779,10 @@ private void initCenterTextView() {
((PasswordEditText) mCenterEditText).setIsAsteriskStyle(mIsAsteriskStyle);
}
}
- mCenterEditTextParams = new LayoutParams(mEditTextWidth, LayoutParams.WRAP_CONTENT);
+ /**
+ * 输入框布局参数
+ */
+ LayoutParams mCenterEditTextParams = new LayoutParams(mEditTextWidth, LayoutParams.WRAP_CONTENT);
mCenterEditTextParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
mCenterEditTextParams.addRule(RelativeLayout.CENTER_VERTICAL, TRUE);
@@ -824,7 +894,8 @@ private void initRightCheckBox() {
if (mRightCheckBox == null) {
mRightCheckBox = new CheckBox(mContext);
}
- mRightCheckBoxParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ //右边checkbox
+ LayoutParams mRightCheckBoxParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
mRightCheckBoxParams.addRule(ALIGN_PARENT_RIGHT, TRUE);
mRightCheckBoxParams.addRule(RelativeLayout.CENTER_VERTICAL, TRUE);
@@ -847,7 +918,7 @@ private void initRightSwitch() {
if (mRightSwitch == null) {
mRightSwitch = new Switch(mContext);
}
- mRightSwitchParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ LayoutParams mRightSwitchParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
mRightSwitchParams.addRule(ALIGN_PARENT_RIGHT, TRUE);
mRightSwitchParams.addRule(RelativeLayout.CENTER_VERTICAL, TRUE);
@@ -1009,6 +1080,8 @@ private void setGravity(BaseTextView baseTextView, int gravity) {
case GRAVITY_RIGHT_CENTER:
baseTextView.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL);
break;
+ default:
+ break;
}
}
@@ -1074,6 +1147,8 @@ private void initDividerLineView() {
setTopDividerLineView();
setBottomDividerLineView();
break;
+ default:
+ break;
}
}
@@ -1149,22 +1224,21 @@ private void initBottomDividerLineView(int marginLeft, int marginRight) {
*
* @param baseTextView baseTextView
*/
- private void setDefaultLeftViewClickListener(BaseTextView baseTextView) {
+ private void setDefaultLeftViewClickListener(final BaseTextView baseTextView) {
if (baseTextView != null) {
if (mLeftTopTvClickListener != null) {
baseTextView.getTopTextView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mLeftTopTvClickListener.onClickListener();
+ mLeftTopTvClickListener.onClick(baseTextView.getTopTextView());
}
});
}
-
if (mLeftTvClickListener != null) {
baseTextView.getCenterTextView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mLeftTvClickListener.onClickListener();
+ mLeftTvClickListener.onClick(baseTextView.getCenterTextView());
}
});
}
@@ -1172,7 +1246,7 @@ public void onClick(View v) {
baseTextView.getBottomTextView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mLeftBottomTvClickListener.onClickListener();
+ mLeftBottomTvClickListener.onClick(baseTextView.getBottomTextView());
}
});
}
@@ -1185,22 +1259,21 @@ public void onClick(View v) {
*
* @param baseTextView baseTextView
*/
- private void setDefaultCenterViewClickListener(BaseTextView baseTextView) {
+ private void setDefaultCenterViewClickListener(final BaseTextView baseTextView) {
if (baseTextView != null) {
if (mCenterTopTvClickListener != null) {
baseTextView.getTopTextView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mCenterTopTvClickListener.onClickListener();
+ mCenterTopTvClickListener.onClick(baseTextView.getTopTextView());
}
});
}
-
if (mCenterTvClickListener != null) {
baseTextView.getCenterTextView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mCenterTvClickListener.onClickListener();
+ mCenterTvClickListener.onClick(baseTextView.getCenterTextView());
}
});
}
@@ -1208,7 +1281,7 @@ public void onClick(View v) {
baseTextView.getBottomTextView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mCenterBottomTvClickListener.onClickListener();
+ mCenterBottomTvClickListener.onClick(baseTextView.getBottomTextView());
}
});
}
@@ -1222,22 +1295,21 @@ public void onClick(View v) {
*
* @param baseTextView baseTextView
*/
- private void setDefaultRightViewClickListener(BaseTextView baseTextView) {
+ private void setDefaultRightViewClickListener(final BaseTextView baseTextView) {
if (baseTextView != null) {
if (mRightTopTvClickListener != null) {
baseTextView.getTopTextView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mRightTopTvClickListener.onClickListener();
+ mRightTopTvClickListener.onClick(baseTextView.getTopTextView());
}
});
}
-
if (mRightTvClickListener != null) {
baseTextView.getCenterTextView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mRightTvClickListener.onClickListener();
+ mRightTvClickListener.onClick(baseTextView.getCenterTextView());
}
});
}
@@ -1245,7 +1317,7 @@ public void onClick(View v) {
baseTextView.getBottomTextView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mRightBottomTvClickListener.onClickListener();
+ mRightBottomTvClickListener.onClick(baseTextView.getBottomTextView());
}
});
}
@@ -2130,7 +2202,7 @@ public SuperTextView setOnSuperTextViewClickListener(OnSuperTextViewClickListene
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mSuperTextViewClickListener.onClickListener(SuperTextView.this);
+ mSuperTextViewClickListener.onClick(SuperTextView.this);
}
});
}
@@ -2218,13 +2290,13 @@ public SuperTextView setRightBottomTvClickListener(OnRightBottomTvClickListener
}
public SuperTextView setLeftImageViewClickListener(OnLeftImageViewClickListener listener) {
- this.mLeftImageViewClickListener = listener;
+ mLeftImageViewClickListener = listener;
if (mLeftIconIV != null) {
mLeftIconIV.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mLeftImageViewClickListener.onClickListener(mLeftIconIV);
+ mLeftImageViewClickListener.onClick(mLeftIconIV);
}
});
}
@@ -2237,7 +2309,7 @@ public SuperTextView setRightImageViewClickListener(final OnRightImageViewClickL
mRightIconIV.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mRightImageViewClickListener.onClickListener(mRightIconIV);
+ mRightImageViewClickListener.onClick(mRightIconIV);
}
});
}
@@ -2280,59 +2352,56 @@ public void setTypeface(Typeface typeface) {
}
////////////////////////////////////////////////////////////////////////////////////
+
public interface OnSuperTextViewClickListener {
- void onClickListener(SuperTextView superTextView);
+ void onClick(SuperTextView superTextView);
}
public interface OnLeftTopTvClickListener {
- void onClickListener();
+ void onClick(TextView textView);
}
public interface OnLeftTvClickListener {
- void onClickListener();
+ void onClick(TextView textView);
}
public interface OnLeftBottomTvClickListener {
- void onClickListener();
+ void onClick(TextView textView);
}
public interface OnCenterTopTvClickListener {
- void onClickListener();
- }
-
- public interface OnCenterEditTextClickListener {
- void onClickListener();
+ void onClick(TextView textView);
}
public interface OnCenterTvClickListener {
- void onClickListener();
+ void onClick(TextView textView);
}
public interface OnCenterBottomTvClickListener {
- void onClickListener();
+ void onClick(TextView textView);
}
public interface OnRightTopTvClickListener {
- void onClickListener();
+ void onClick(TextView textView);
}
public interface OnRightTvClickListener {
- void onClickListener();
+ void onClick(TextView textView);
}
public interface OnRightBottomTvClickListener {
- void onClickListener();
+ void onClick(TextView textView);
}
public interface OnLeftImageViewClickListener {
- void onClickListener(ImageView imageView);
+ void onClick(ImageView imageView);
}
public interface OnRightImageViewClickListener {
- void onClickListener(ImageView imageView);
+ void onClick(ImageView imageView);
}
- // TODO: 2017/7/10 一下是shape相关属性方法
+ //=================以下是shape相关属性方法================//
/**
* 获取设置之后的Selector
@@ -2383,7 +2452,8 @@ private void setBorder() {
*/
private void setRadius() {
if (mCornersRadius != 0) {
- mGradientDrawable.setCornerRadius(mCornersRadius);//设置圆角的半径
+ //设置圆角的半径
+ mGradientDrawable.setCornerRadius(mCornersRadius);
} else {
//1、2两个参数表示左上角,3、4表示右上角,5、6表示右下角,7、8表示左下角
mGradientDrawable.setCornerRadii(
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/toast/XToast.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/toast/XToast.java
index 341eedb8..f0dcecc4 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/toast/XToast.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/toast/XToast.java
@@ -296,7 +296,7 @@ public static Toast custom(@NonNull Context context, @NonNull CharSequence messa
@ColorInt int tintColor, @ColorInt int textColor, int duration,
boolean withIcon, boolean shouldTint) {
final Toast currentToast = Toast.makeText(context, "", duration);
- final View toastLayout = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.xtoast_layout, null);
+ final View toastLayout = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.xui_layout_xtoast, null);
final ImageView toastIcon = toastLayout.findViewById(R.id.toast_icon);
final TextView toastTextView = toastLayout.findViewById(R.id.toast_text);
Drawable drawableFrame;
diff --git a/xui_lib/src/main/res/anim/ddm_mask_in.xml b/xui_lib/src/main/res/anim/ddm_mask_in.xml
new file mode 100644
index 00000000..9b1b02de
--- /dev/null
+++ b/xui_lib/src/main/res/anim/ddm_mask_in.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/anim/ddm_mask_out.xml b/xui_lib/src/main/res/anim/ddm_mask_out.xml
new file mode 100644
index 00000000..4512c462
--- /dev/null
+++ b/xui_lib/src/main/res/anim/ddm_mask_out.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/anim/ddm_menu_in.xml b/xui_lib/src/main/res/anim/ddm_menu_in.xml
new file mode 100644
index 00000000..c3b3599e
--- /dev/null
+++ b/xui_lib/src/main/res/anim/ddm_menu_in.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/anim/ddm_menu_out.xml b/xui_lib/src/main/res/anim/ddm_menu_out.xml
new file mode 100644
index 00000000..008ede2b
--- /dev/null
+++ b/xui_lib/src/main/res/anim/ddm_menu_out.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/anim/picker_view_dialog_scale_in.xml b/xui_lib/src/main/res/anim/picker_view_dialog_scale_in.xml
index b38a4dd5..8b319c66 100644
--- a/xui_lib/src/main/res/anim/picker_view_dialog_scale_in.xml
+++ b/xui_lib/src/main/res/anim/picker_view_dialog_scale_in.xml
@@ -1,19 +1,16 @@
+
-
-
-
-
-
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/anim/picker_view_dialog_scale_out.xml b/xui_lib/src/main/res/anim/picker_view_dialog_scale_out.xml
index 172a97b5..f6e487b3 100644
--- a/xui_lib/src/main/res/anim/picker_view_dialog_scale_out.xml
+++ b/xui_lib/src/main/res/anim/picker_view_dialog_scale_out.xml
@@ -1,7 +1,5 @@
-
-
-
-
+
+
diff --git a/xui_lib/src/main/res/anim/pop_grow_from_bottomleft_to_topright.xml b/xui_lib/src/main/res/anim/pop_grow_from_bottomleft_to_topright.xml
index a4bf4ea2..108eb2b3 100755
--- a/xui_lib/src/main/res/anim/pop_grow_from_bottomleft_to_topright.xml
+++ b/xui_lib/src/main/res/anim/pop_grow_from_bottomleft_to_topright.xml
@@ -1,14 +1,16 @@
-
-
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/anim/pop_grow_from_bottomright_to_topleft.xml b/xui_lib/src/main/res/anim/pop_grow_from_bottomright_to_topleft.xml
index 1922b2b0..03735df1 100755
--- a/xui_lib/src/main/res/anim/pop_grow_from_bottomright_to_topleft.xml
+++ b/xui_lib/src/main/res/anim/pop_grow_from_bottomright_to_topleft.xml
@@ -1,14 +1,16 @@
-
-
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/anim/pop_grow_from_top.xml b/xui_lib/src/main/res/anim/pop_grow_from_top.xml
index ffd722c3..8e67492b 100755
--- a/xui_lib/src/main/res/anim/pop_grow_from_top.xml
+++ b/xui_lib/src/main/res/anim/pop_grow_from_top.xml
@@ -1,14 +1,16 @@
-
-
+
+
diff --git a/xui_lib/src/main/res/anim/pop_grow_from_topleft_to_bottomright.xml b/xui_lib/src/main/res/anim/pop_grow_from_topleft_to_bottomright.xml
index b67ebe5e..cf0170c1 100755
--- a/xui_lib/src/main/res/anim/pop_grow_from_topleft_to_bottomright.xml
+++ b/xui_lib/src/main/res/anim/pop_grow_from_topleft_to_bottomright.xml
@@ -1,14 +1,16 @@
-
-
+
+
diff --git a/xui_lib/src/main/res/anim/pop_grow_from_topright_to_bottomleft.xml b/xui_lib/src/main/res/anim/pop_grow_from_topright_to_bottomleft.xml
index fb19004a..1033052a 100755
--- a/xui_lib/src/main/res/anim/pop_grow_from_topright_to_bottomleft.xml
+++ b/xui_lib/src/main/res/anim/pop_grow_from_topright_to_bottomleft.xml
@@ -1,14 +1,16 @@
-
-
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/anim/pop_shrink_from_bottom.xml b/xui_lib/src/main/res/anim/pop_shrink_from_bottom.xml
index a98d592a..01261219 100755
--- a/xui_lib/src/main/res/anim/pop_shrink_from_bottom.xml
+++ b/xui_lib/src/main/res/anim/pop_shrink_from_bottom.xml
@@ -1,14 +1,16 @@
-
-
+
+
diff --git a/xui_lib/src/main/res/anim/pop_shrink_from_bottomleft_to_topright.xml b/xui_lib/src/main/res/anim/pop_shrink_from_bottomleft_to_topright.xml
index ebde343e..d2b9ad4b 100755
--- a/xui_lib/src/main/res/anim/pop_shrink_from_bottomleft_to_topright.xml
+++ b/xui_lib/src/main/res/anim/pop_shrink_from_bottomleft_to_topright.xml
@@ -1,14 +1,16 @@
-
-
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/anim/pop_shrink_from_bottomright_to_topleft.xml b/xui_lib/src/main/res/anim/pop_shrink_from_bottomright_to_topleft.xml
index d4ed5134..4ff89610 100755
--- a/xui_lib/src/main/res/anim/pop_shrink_from_bottomright_to_topleft.xml
+++ b/xui_lib/src/main/res/anim/pop_shrink_from_bottomright_to_topleft.xml
@@ -1,14 +1,16 @@
-
-
+
+
diff --git a/xui_lib/src/main/res/anim/pop_shrink_from_top.xml b/xui_lib/src/main/res/anim/pop_shrink_from_top.xml
index 89cd8f4f..0bb4517d 100755
--- a/xui_lib/src/main/res/anim/pop_shrink_from_top.xml
+++ b/xui_lib/src/main/res/anim/pop_shrink_from_top.xml
@@ -1,14 +1,16 @@
-
-
+
+
diff --git a/xui_lib/src/main/res/anim/pop_shrink_from_topleft_to_bottomright.xml b/xui_lib/src/main/res/anim/pop_shrink_from_topleft_to_bottomright.xml
index a39681a8..6a0b16fd 100755
--- a/xui_lib/src/main/res/anim/pop_shrink_from_topleft_to_bottomright.xml
+++ b/xui_lib/src/main/res/anim/pop_shrink_from_topleft_to_bottomright.xml
@@ -1,14 +1,16 @@
-
-
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/anim/pop_shrink_from_topright_to_bottomleft.xml b/xui_lib/src/main/res/anim/pop_shrink_from_topright_to_bottomleft.xml
index d4064fcc..5031f195 100755
--- a/xui_lib/src/main/res/anim/pop_shrink_from_topright_to_bottomleft.xml
+++ b/xui_lib/src/main/res/anim/pop_shrink_from_topright_to_bottomleft.xml
@@ -1,14 +1,16 @@
-
-
+
+
diff --git a/xui_lib/src/main/res/anim/srb_rotation.xml b/xui_lib/src/main/res/anim/srb_rotation.xml
index b4582089..55f7db1f 100644
--- a/xui_lib/src/main/res/anim/srb_rotation.xml
+++ b/xui_lib/src/main/res/anim/srb_rotation.xml
@@ -1,11 +1,10 @@
\ No newline at end of file
+ android:duration="750"
+ android:fillAfter="true"
+ android:fromDegrees="0.0"
+ android:interpolator="@android:anim/decelerate_interpolator"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:repeatCount="0"
+ android:toDegrees="360.0" />
\ No newline at end of file
diff --git a/xui_lib/src/main/res/color/xui_selector_content_text_color.xml b/xui_lib/src/main/res/color/xui_selector_content_text_color.xml
new file mode 100644
index 00000000..eb91c22a
--- /dev/null
+++ b/xui_lib/src/main/res/color/xui_selector_content_text_color.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/drawable-v17/xui_config_list_item_selector.xml b/xui_lib/src/main/res/drawable-v17/xui_config_list_item_selector.xml
index 9296c89e..ff6d61af 100644
--- a/xui_lib/src/main/res/drawable-v17/xui_config_list_item_selector.xml
+++ b/xui_lib/src/main/res/drawable-v17/xui_config_list_item_selector.xml
@@ -1,5 +1,6 @@
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/drawable-v21/ms_ic_arrow_down.xml b/xui_lib/src/main/res/drawable-v21/ms_ic_arrow_down.xml
index 25a830be..22e2cdca 100755
--- a/xui_lib/src/main/res/drawable-v21/ms_ic_arrow_down.xml
+++ b/xui_lib/src/main/res/drawable-v21/ms_ic_arrow_down.xml
@@ -5,6 +5,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
\ No newline at end of file
diff --git a/xui_lib/src/main/res/drawable/ddm_ic_arrow_down.xml b/xui_lib/src/main/res/drawable/ddm_ic_arrow_down.xml
new file mode 100644
index 00000000..0d133652
--- /dev/null
+++ b/xui_lib/src/main/res/drawable/ddm_ic_arrow_down.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/xui_lib/src/main/res/drawable/ddm_ic_arrow_up.xml b/xui_lib/src/main/res/drawable/ddm_ic_arrow_up.xml
new file mode 100644
index 00000000..022c2ae1
--- /dev/null
+++ b/xui_lib/src/main/res/drawable/ddm_ic_arrow_up.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/xui_lib/src/main/res/drawable/ms_ic_arrow_down.xml b/xui_lib/src/main/res/drawable/ms_ic_arrow_down.xml
index 25a830be..22e2cdca 100755
--- a/xui_lib/src/main/res/drawable/ms_ic_arrow_down.xml
+++ b/xui_lib/src/main/res/drawable/ms_ic_arrow_down.xml
@@ -5,6 +5,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
\ No newline at end of file
diff --git a/xui_lib/src/main/res/drawable/xui_config_list_item_selector.xml b/xui_lib/src/main/res/drawable/xui_config_list_item_selector.xml
index 469a9b1c..1608777e 100755
--- a/xui_lib/src/main/res/drawable/xui_config_list_item_selector.xml
+++ b/xui_lib/src/main/res/drawable/xui_config_list_item_selector.xml
@@ -1,5 +1,6 @@
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/drawable/xui_ic_expand_arrow_down.xml b/xui_lib/src/main/res/drawable/xui_ic_expand_arrow_down.xml
new file mode 100644
index 00000000..023b160e
--- /dev/null
+++ b/xui_lib/src/main/res/drawable/xui_ic_expand_arrow_down.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/xui_lib/src/main/res/drawable/xui_ic_expand_arrow_up.xml b/xui_lib/src/main/res/drawable/xui_ic_expand_arrow_up.xml
new file mode 100644
index 00000000..5ee3c528
--- /dev/null
+++ b/xui_lib/src/main/res/drawable/xui_ic_expand_arrow_up.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/xui_lib/src/main/res/layout-large/xtoast_layout.xml b/xui_lib/src/main/res/layout-large/xui_layout_xtoast.xml
similarity index 100%
rename from xui_lib/src/main/res/layout-large/xtoast_layout.xml
rename to xui_lib/src/main/res/layout-large/xui_layout_xtoast.xml
diff --git a/xui_lib/src/main/res/layout-xlarge/xtoast_layout.xml b/xui_lib/src/main/res/layout-xlarge/xui_layout_xtoast.xml
similarity index 100%
rename from xui_lib/src/main/res/layout-xlarge/xtoast_layout.xml
rename to xui_lib/src/main/res/layout-xlarge/xui_layout_xtoast.xml
diff --git a/xui_lib/src/main/res/layout/md_dialog_basic.xml b/xui_lib/src/main/res/layout/md_layout_dialog_basic.xml
old mode 100755
new mode 100644
similarity index 93%
rename from xui_lib/src/main/res/layout/md_dialog_basic.xml
rename to xui_lib/src/main/res/layout/md_layout_dialog_basic.xml
index d35447e6..3e45f19c
--- a/xui_lib/src/main/res/layout/md_dialog_basic.xml
+++ b/xui_lib/src/main/res/layout/md_layout_dialog_basic.xml
@@ -23,7 +23,7 @@
android:orientation="vertical"
app:md_reduce_padding_no_title_no_buttons="false">
-
+
-
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/md_dialog_basic_check.xml b/xui_lib/src/main/res/layout/md_layout_dialog_basic_check.xml
old mode 100755
new mode 100644
similarity index 95%
rename from xui_lib/src/main/res/layout/md_dialog_basic_check.xml
rename to xui_lib/src/main/res/layout/md_layout_dialog_basic_check.xml
index b5594944..871805a5
--- a/xui_lib/src/main/res/layout/md_dialog_basic_check.xml
+++ b/xui_lib/src/main/res/layout/md_layout_dialog_basic_check.xml
@@ -23,7 +23,7 @@
android:orientation="vertical"
app:md_reduce_padding_no_title_no_buttons="false">
-
+
-
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/md_dialog_custom.xml b/xui_lib/src/main/res/layout/md_layout_dialog_custom.xml
old mode 100755
new mode 100644
similarity index 90%
rename from xui_lib/src/main/res/layout/md_dialog_custom.xml
rename to xui_lib/src/main/res/layout/md_layout_dialog_custom.xml
index 74119e98..81a50466
--- a/xui_lib/src/main/res/layout/md_dialog_custom.xml
+++ b/xui_lib/src/main/res/layout/md_layout_dialog_custom.xml
@@ -22,13 +22,13 @@
android:layout_height="wrap_content"
android:orientation="vertical">
-
+
-
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/md_dialog_input.xml b/xui_lib/src/main/res/layout/md_layout_dialog_input.xml
old mode 100755
new mode 100644
similarity index 96%
rename from xui_lib/src/main/res/layout/md_dialog_input.xml
rename to xui_lib/src/main/res/layout/md_layout_dialog_input.xml
index 86ffad10..fb9c9d57
--- a/xui_lib/src/main/res/layout/md_dialog_input.xml
+++ b/xui_lib/src/main/res/layout/md_layout_dialog_input.xml
@@ -24,7 +24,7 @@
android:orientation="vertical"
app:md_reduce_padding_no_title_no_buttons="false">
-
+
-
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/md_dialog_input_check.xml b/xui_lib/src/main/res/layout/md_layout_dialog_input_check.xml
old mode 100755
new mode 100644
similarity index 96%
rename from xui_lib/src/main/res/layout/md_dialog_input_check.xml
rename to xui_lib/src/main/res/layout/md_layout_dialog_input_check.xml
index a15a9def..41926a32
--- a/xui_lib/src/main/res/layout/md_dialog_input_check.xml
+++ b/xui_lib/src/main/res/layout/md_layout_dialog_input_check.xml
@@ -24,7 +24,7 @@
android:orientation="vertical"
app:md_reduce_padding_no_title_no_buttons="false">
-
+
-
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/md_dialog_list.xml b/xui_lib/src/main/res/layout/md_layout_dialog_list.xml
old mode 100755
new mode 100644
similarity index 95%
rename from xui_lib/src/main/res/layout/md_dialog_list.xml
rename to xui_lib/src/main/res/layout/md_layout_dialog_list.xml
index d9972db7..906ab0fe
--- a/xui_lib/src/main/res/layout/md_dialog_list.xml
+++ b/xui_lib/src/main/res/layout/md_layout_dialog_list.xml
@@ -21,7 +21,7 @@
android:layout_height="wrap_content"
android:orientation="vertical">
-
+
-
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/md_dialog_list_check.xml b/xui_lib/src/main/res/layout/md_layout_dialog_list_check.xml
old mode 100755
new mode 100644
similarity index 96%
rename from xui_lib/src/main/res/layout/md_dialog_list_check.xml
rename to xui_lib/src/main/res/layout/md_layout_dialog_list_check.xml
index 3c9e30c4..60bc5745
--- a/xui_lib/src/main/res/layout/md_dialog_list_check.xml
+++ b/xui_lib/src/main/res/layout/md_layout_dialog_list_check.xml
@@ -21,7 +21,7 @@
android:layout_height="wrap_content"
android:orientation="vertical">
-
+
-
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/md_dialog_progress.xml b/xui_lib/src/main/res/layout/md_layout_dialog_progress.xml
old mode 100755
new mode 100644
similarity index 89%
rename from xui_lib/src/main/res/layout/md_dialog_progress.xml
rename to xui_lib/src/main/res/layout/md_layout_dialog_progress.xml
index 8a19a156..d02ca5e8
--- a/xui_lib/src/main/res/layout/md_dialog_progress.xml
+++ b/xui_lib/src/main/res/layout/md_layout_dialog_progress.xml
@@ -23,7 +23,7 @@
android:orientation="vertical"
app:md_reduce_padding_no_title_no_buttons="false">
-
+
-
+
-
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/md_dialog_progress_indeterminate.xml b/xui_lib/src/main/res/layout/md_layout_dialog_progress_indeterminate.xml
old mode 100755
new mode 100644
similarity index 85%
rename from xui_lib/src/main/res/layout/md_dialog_progress_indeterminate.xml
rename to xui_lib/src/main/res/layout/md_layout_dialog_progress_indeterminate.xml
index f2843c08..f949c18f
--- a/xui_lib/src/main/res/layout/md_dialog_progress_indeterminate.xml
+++ b/xui_lib/src/main/res/layout/md_layout_dialog_progress_indeterminate.xml
@@ -23,10 +23,10 @@
android:orientation="vertical"
app:md_reduce_padding_no_title_no_buttons="false">
-
+
-
+
-
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/md_dialog_progress_indeterminate_horizontal.xml b/xui_lib/src/main/res/layout/md_layout_dialog_progress_indeterminate_horizontal.xml
old mode 100755
new mode 100644
similarity index 88%
rename from xui_lib/src/main/res/layout/md_dialog_progress_indeterminate_horizontal.xml
rename to xui_lib/src/main/res/layout/md_layout_dialog_progress_indeterminate_horizontal.xml
index e143c4ab..7a0ab2a9
--- a/xui_lib/src/main/res/layout/md_dialog_progress_indeterminate_horizontal.xml
+++ b/xui_lib/src/main/res/layout/md_layout_dialog_progress_indeterminate_horizontal.xml
@@ -23,7 +23,7 @@
android:orientation="vertical"
app:md_reduce_padding_no_title_no_buttons="false">
-
+
-
+
-
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/md_listitem.xml b/xui_lib/src/main/res/layout/md_layout_listitem.xml
old mode 100755
new mode 100644
similarity index 100%
rename from xui_lib/src/main/res/layout/md_listitem.xml
rename to xui_lib/src/main/res/layout/md_layout_listitem.xml
diff --git a/xui_lib/src/main/res/layout/md_listitem_multichoice.xml b/xui_lib/src/main/res/layout/md_layout_listitem_multichoice.xml
old mode 100755
new mode 100644
similarity index 100%
rename from xui_lib/src/main/res/layout/md_listitem_multichoice.xml
rename to xui_lib/src/main/res/layout/md_layout_listitem_multichoice.xml
diff --git a/xui_lib/src/main/res/layout/md_listitem_singlechoice.xml b/xui_lib/src/main/res/layout/md_layout_listitem_singlechoice.xml
old mode 100755
new mode 100644
similarity index 100%
rename from xui_lib/src/main/res/layout/md_listitem_singlechoice.xml
rename to xui_lib/src/main/res/layout/md_layout_listitem_singlechoice.xml
diff --git a/xui_lib/src/main/res/layout/md_preference_custom.xml b/xui_lib/src/main/res/layout/md_layout_preference_custom.xml
similarity index 100%
rename from xui_lib/src/main/res/layout/md_preference_custom.xml
rename to xui_lib/src/main/res/layout/md_layout_preference_custom.xml
diff --git a/xui_lib/src/main/res/layout/md_simplelist_item.xml b/xui_lib/src/main/res/layout/md_layout_simplelist_item.xml
old mode 100755
new mode 100644
similarity index 100%
rename from xui_lib/src/main/res/layout/md_simplelist_item.xml
rename to xui_lib/src/main/res/layout/md_layout_simplelist_item.xml
diff --git a/xui_lib/src/main/res/layout/md_stub_actionbuttons.xml b/xui_lib/src/main/res/layout/md_layout_stub_actionbuttons.xml
old mode 100755
new mode 100644
similarity index 100%
rename from xui_lib/src/main/res/layout/md_stub_actionbuttons.xml
rename to xui_lib/src/main/res/layout/md_layout_stub_actionbuttons.xml
diff --git a/xui_lib/src/main/res/layout/md_stub_inputpref.xml b/xui_lib/src/main/res/layout/md_layout_stub_inputpref.xml
similarity index 100%
rename from xui_lib/src/main/res/layout/md_stub_inputpref.xml
rename to xui_lib/src/main/res/layout/md_layout_stub_inputpref.xml
diff --git a/xui_lib/src/main/res/layout/md_stub_progress.xml b/xui_lib/src/main/res/layout/md_layout_stub_progress.xml
old mode 100755
new mode 100644
similarity index 100%
rename from xui_lib/src/main/res/layout/md_stub_progress.xml
rename to xui_lib/src/main/res/layout/md_layout_stub_progress.xml
diff --git a/xui_lib/src/main/res/layout/md_stub_progress_indeterminate.xml b/xui_lib/src/main/res/layout/md_layout_stub_progress_indeterminate.xml
old mode 100755
new mode 100644
similarity index 100%
rename from xui_lib/src/main/res/layout/md_stub_progress_indeterminate.xml
rename to xui_lib/src/main/res/layout/md_layout_stub_progress_indeterminate.xml
diff --git a/xui_lib/src/main/res/layout/md_stub_progress_indeterminate_horizontal.xml b/xui_lib/src/main/res/layout/md_layout_stub_progress_indeterminate_horizontal.xml
old mode 100755
new mode 100644
similarity index 100%
rename from xui_lib/src/main/res/layout/md_stub_progress_indeterminate_horizontal.xml
rename to xui_lib/src/main/res/layout/md_layout_stub_progress_indeterminate_horizontal.xml
diff --git a/xui_lib/src/main/res/layout/md_stub_titleframe.xml b/xui_lib/src/main/res/layout/md_layout_stub_titleframe.xml
old mode 100755
new mode 100644
similarity index 100%
rename from xui_lib/src/main/res/layout/md_stub_titleframe.xml
rename to xui_lib/src/main/res/layout/md_layout_stub_titleframe.xml
diff --git a/xui_lib/src/main/res/layout/md_stub_titleframe_lesspadding.xml b/xui_lib/src/main/res/layout/md_layout_stub_titleframe_lesspadding.xml
old mode 100755
new mode 100644
similarity index 100%
rename from xui_lib/src/main/res/layout/md_stub_titleframe_lesspadding.xml
rename to xui_lib/src/main/res/layout/md_layout_stub_titleframe_lesspadding.xml
diff --git a/xui_lib/src/main/res/layout/ms_list_item.xml b/xui_lib/src/main/res/layout/ms_layout_list_item.xml
old mode 100755
new mode 100644
similarity index 100%
rename from xui_lib/src/main/res/layout/ms_list_item.xml
rename to xui_lib/src/main/res/layout/ms_layout_list_item.xml
diff --git a/xui_lib/src/main/res/layout/msv_empty_view.xml b/xui_lib/src/main/res/layout/msv_layout_empty_view.xml
similarity index 100%
rename from xui_lib/src/main/res/layout/msv_empty_view.xml
rename to xui_lib/src/main/res/layout/msv_layout_empty_view.xml
diff --git a/xui_lib/src/main/res/layout/msv_error_view.xml b/xui_lib/src/main/res/layout/msv_layout_error_view.xml
similarity index 100%
rename from xui_lib/src/main/res/layout/msv_error_view.xml
rename to xui_lib/src/main/res/layout/msv_layout_error_view.xml
diff --git a/xui_lib/src/main/res/layout/msv_loading_view.xml b/xui_lib/src/main/res/layout/msv_layout_loading_view.xml
similarity index 100%
rename from xui_lib/src/main/res/layout/msv_loading_view.xml
rename to xui_lib/src/main/res/layout/msv_layout_loading_view.xml
diff --git a/xui_lib/src/main/res/layout/msv_no_network_view.xml b/xui_lib/src/main/res/layout/msv_layout_no_network_view.xml
similarity index 100%
rename from xui_lib/src/main/res/layout/msv_no_network_view.xml
rename to xui_lib/src/main/res/layout/msv_layout_no_network_view.xml
diff --git a/xui_lib/src/main/res/layout/xui_adapter_listview_simple_item.xml b/xui_lib/src/main/res/layout/xui_adapter_listview_simple_item.xml
index a7184f8a..de08fd75 100644
--- a/xui_lib/src/main/res/layout/xui_adapter_listview_simple_item.xml
+++ b/xui_lib/src/main/res/layout/xui_adapter_listview_simple_item.xml
@@ -1,8 +1,9 @@
+ android:textSize="?attr/xui_config_size_content_text"
+ tools:text="设置" />
diff --git a/xui_lib/src/main/res/layout/xui_layout_expand_child_item.xml b/xui_lib/src/main/res/layout/xui_layout_expand_child_item.xml
new file mode 100644
index 00000000..1aa396d1
--- /dev/null
+++ b/xui_lib/src/main/res/layout/xui_layout_expand_child_item.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/xui_layout_expand_group_item.xml b/xui_lib/src/main/res/layout/xui_layout_expand_group_item.xml
new file mode 100644
index 00000000..74674f3e
--- /dev/null
+++ b/xui_lib/src/main/res/layout/xui_layout_expand_group_item.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/layout/layout_photo_editor_image.xml b/xui_lib/src/main/res/layout/xui_layout_photo_editor_image.xml
similarity index 100%
rename from xui_lib/src/main/res/layout/layout_photo_editor_image.xml
rename to xui_lib/src/main/res/layout/xui_layout_photo_editor_image.xml
diff --git a/xui_lib/src/main/res/layout/layout_photo_editor_text.xml b/xui_lib/src/main/res/layout/xui_layout_photo_editor_text.xml
similarity index 100%
rename from xui_lib/src/main/res/layout/layout_photo_editor_text.xml
rename to xui_lib/src/main/res/layout/xui_layout_photo_editor_text.xml
diff --git a/xui_lib/src/main/res/layout/xtoast_layout.xml b/xui_lib/src/main/res/layout/xui_layout_xtoast.xml
similarity index 100%
rename from xui_lib/src/main/res/layout/xtoast_layout.xml
rename to xui_lib/src/main/res/layout/xui_layout_xtoast.xml
diff --git a/xui_lib/src/main/res/values/stv_attrs.xml b/xui_lib/src/main/res/values/stv_attrs.xml
index 61819303..ed37a908 100755
--- a/xui_lib/src/main/res/values/stv_attrs.xml
+++ b/xui_lib/src/main/res/values/stv_attrs.xml
@@ -162,20 +162,22 @@
-
-
+
+
+
+
+
+
+
-
-
-
diff --git a/xui_lib/src/main/res/values/xui_attrs.xml b/xui_lib/src/main/res/values/xui_attrs.xml
index cd6be9fd..c443f752 100755
--- a/xui_lib/src/main/res/values/xui_attrs.xml
+++ b/xui_lib/src/main/res/values/xui_attrs.xml
@@ -123,6 +123,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1137,18 +1150,18 @@
-
-
-
+
+
+
-
+
-
+
-
+
-
+
@@ -1288,8 +1301,12 @@
-
+
+
+
+
+
@@ -1371,6 +1388,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1415,6 +1469,12 @@
+
+
+
+
+
+
diff --git a/xui_lib/src/main/res/values/xui_colors.xml b/xui_lib/src/main/res/values/xui_colors.xml
index 71f7ed19..5d22aa44 100755
--- a/xui_lib/src/main/res/values/xui_colors.xml
+++ b/xui_lib/src/main/res/values/xui_colors.xml
@@ -82,6 +82,8 @@
#353A3E
#555555
+
+ #88888888
+ 1dp
+ 0.5dp
+ 10dp
+ 14sp
+ 5dp
+ 12dp
+
+
20sp
20dp
diff --git a/xui_lib/src/main/res/values/xui_public.xml b/xui_lib/src/main/res/values/xui_public.xml
index b750f96f..62cf99d3 100644
--- a/xui_lib/src/main/res/values/xui_public.xml
+++ b/xui_lib/src/main/res/values/xui_public.xml
@@ -162,13 +162,12 @@
-
-
-
-
-
+
+
+
+
diff --git a/xui_lib/src/main/res/values/xui_styles_widget.xml b/xui_lib/src/main/res/values/xui_styles_widget.xml
index 8f0d048e..ae92608b 100644
--- a/xui_lib/src/main/res/values/xui_styles_widget.xml
+++ b/xui_lib/src/main/res/values/xui_styles_widget.xml
@@ -411,7 +411,8 @@
- ?attr/xui_config_size_edittext_helper_text
- ?attr/xui_config_size_edittext_helper_text
- - ?attr/xui_config_size_edittext_components_spacing
+ - ?attr/xui_config_size_edittext_components_spacing
+
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/values/xui_themes.xml b/xui_lib/src/main/res/values/xui_themes.xml
index 188a7547..4851fd58 100755
--- a/xui_lib/src/main/res/values/xui_themes.xml
+++ b/xui_lib/src/main/res/values/xui_themes.xml
@@ -267,7 +267,7 @@
- @style/AutoFitTextView
- @style/RippleView
- @style/BannerLayout
-
+ - @style/DropDownMenu