最近又回归安卓了,写了一阵子java后台和前端vue,最喜欢的还是我的android
话不多说,今天简单写点分享给朋友们
上图:
介绍:
顶部是个include
底部是listview
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/cs_F0F5FA" android:fitsSystemWindows="false" tools:context="com.yc.hospital.activity.MyCouponActivity"> <!--我的优惠券false--> <include android:id="@+id/include_top_green" layout="@layout/include_top_title_green" android:visibility="visible" /> <!--优惠券列表--> <ListView android:id="@+id/lv_coupon" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/include_top_green" android:layout_marginBottom="@dimen/ds_10dp" android:layout_marginTop="@dimen/ds_11dp" android:divider="@null" android:scrollbars="none" /> </RelativeLayout>
然后是activity
package com.yc.hospital.activity; import android.view.View; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import com.yc.hospital.R; import com.yc.hospital.adapter.MyCouponAdapter; import com.yc.hospital.bean.MyCouponBean; import com.yc.hospital.utils.TouchDelegateUtils; import java.util.ArrayList; import java.util.List; import butterknife.BindView; /** * ================================================ * * @author:vip 版 本:V 1.0.0 * 创建日期:2018/12/14 * 描 述:我的优惠券 * 注:lv滑动,顶部绿色图片沉浸 * 修订历史: * ================================================ */ public class MyCouponActivity extends BaseActivity { @BindView(R.id.iv_back) ImageView ivBack; @BindView(R.id.tv_tittle) TextView tvTittle; @BindView(R.id.tv_base_some) TextView tvBaseSome; @BindView(R.id.iv_white_search) ImageButton ivWhiteSearch; @BindView(R.id.tv_add) TextView tvAdd; @BindView(R.id.lv_coupon) ListView lvCoupon; private MyCouponAdapter myCouponAdapter; private List<MyCouponBean.DataBean> myCouponList = new ArrayList<>(); @Override public void initRootView() { setContentView(R.layout.activity_my_coupon); } @Override public void initView() { tvTittle.setText("我的优惠券"); myCouponAdapter = new MyCouponAdapter(mContext, myCouponList); lvCoupon.setAdapter(myCouponAdapter); } @Override public void initData() { MyCouponBean.DataBean dataBean1 = new MyCouponBean.DataBean(); dataBean1.setPrice("10"); dataBean1.setBeginAndOver("有效期 2012-11-01~2019-01-31"); dataBean1.setState("0"); dataBean1.setFullCanUse("满200元可用"); dataBean1.setSource("来源:活动赠送"); MyCouponBean.DataBean dataBean2 = new MyCouponBean.DataBean(); dataBean2.setPrice("1210"); dataBean2.setBeginAndOver("有效期 2013-11-01~2019-01-31"); dataBean2.setState("1"); dataBean2.setFullCanUse("满2000000元可用"); dataBean2.setSource("来源:活动赠送,购买199减99" + "限制感冒药使用"); MyCouponBean.DataBean dataBean3 = new MyCouponBean.DataBean(); dataBean3.setPrice("1022"); dataBean3.setBeginAndOver("有效期 2014-11-01~2019-01-31"); dataBean3.setState("2"); dataBean3.setFullCanUse("满21212300元可用"); dataBean3.setSource("来源:活动赠送,购买11199减99 " + "限制留下的冒药使用"); MyCouponBean.DataBean dataBean4 = new MyCouponBean.DataBean(); dataBean4.setPrice("2312"); dataBean4.setBeginAndOver("有效期 2015-11-01~2019-01-31"); dataBean4.setState("2"); dataBean4.setFullCanUse("满1212121212200元可用"); dataBean4.setSource("来源:上家给的赠送,购买122229减99" + "限制感冒药使用,不排除这个人疯了呢,晚上订餐,晚上吃饭,今天天津很好,我是的撒是大大大大的经济结构钢结构加工加工及"); MyCouponBean.DataBean dataBean5 = new MyCouponBean.DataBean(); dataBean5.setPrice("10.5"); dataBean5.setBeginAndOver("有效期 2016-11-01~2019-01-31"); dataBean5.setState("1"); dataBean5.setFullCanUse("满10元可用"); dataBean5.setSource("来源:实打实大声道,购买122229减99" + "限制感冒药使用,啊实打实大师,晚上订餐,晚上吃饭,阿斯顿阿斯,重中之重222 "); MyCouponBean.DataBean dataBean6 = new MyCouponBean.DataBean(); dataBean6.setPrice("110"); dataBean6.setBeginAndOver("有效期 2017-11-01~2019-01-31"); dataBean6.setState("2"); dataBean6.setFullCanUse("满11100元可用"); dataBean6.setSource("来源:蒂花之秀,购买666629减99" + "限制止咳药,啊实打实大师,晚上订餐,晚上吃饭,阿斯顿阿斯,今天没写了 "); myCouponList.add(dataBean1); myCouponList.add(dataBean2); myCouponList.add(dataBean3); myCouponList.add(dataBean4); myCouponList.add(dataBean5); myCouponList.add(dataBean6); myCouponAdapter.notifyDataSetChanged(); } @Override public void initListener() { ivBack.setOnClickListener(this); //这是增大点击区域的方法,大家不调用也行,自己在布局文件里设置下间距也可以 TouchDelegateUtils.addDefaultScreenArea(ivBack, 55, 55, 55, 55); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.iv_back: finish(); break; default: break; } } }
实体类:
package com.yc.hospital.bean; import java.util.List; /** * ================================================ * * @author:Vip 版 本:V 1.0.0 * 创建日期:2018/12/13 * 描 述:我的优惠券列表实体 * 修订历史: * ================================================ */ public class MyCouponBean extends BaseBean { private String msg; private String code; private List<DataBean> data; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { /** * 价格,满多少可以用,日期,来源,状态 **/ private String price; private String fullCanUse; private String beginAndOver; private String source; private String state; public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public String getBeginAndOver() { return beginAndOver; } public void setBeginAndOver(String beginAndOver) { this.beginAndOver = beginAndOver; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getFullCanUse() { return fullCanUse; } public void setFullCanUse(String fullCanUse) { this.fullCanUse = fullCanUse; } public String getSource() { return source; } public void setSource(String source) { this.source = source; } } }
适配器
package com.yc.hospital.adapter; import android.annotation.SuppressLint; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.RotateAnimation; import android.view.animation.Transformation; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import com.yc.hospital.R; import com.yc.hospital.bean.MyCouponBean; import com.yc.hospital.myview.MoreTextView; import com.yc.hospital.utils.StringUtils; import com.yc.hospital.utils.Tt; import java.util.List; /** * ================================================ * * @author:Vip 版 本:V 1.0.0 * 创建日期:2018/12/14 * 描 述:我的优惠券列表适配器 * 修订历史: * ================================================ */ public class MyCouponAdapter extends BaseAdapter { private List<MyCouponBean.DataBean> mList; private Context mContext; public MyCouponAdapter(Context context, List<MyCouponBean.DataBean> list) { super(); this.mContext = context; this.mList = list; } @Override public int getCount() { return mList.size(); } @Override public MyCouponBean.DataBean getItem(int position) { return mList.get(position); } @Override public long getItemId(int position) { return position; } @SuppressLint("SetTextI18n") @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(mContext).inflate(R.layout.item_my_coupon, parent, false); holder = new ViewHolder(); holder.llAll = convertView.findViewById(R.id.ll_all); holder.tvPrice = convertView.findViewById(R.id.tv_price); holder.tvElement = convertView.findViewById(R.id.tv_element); holder.tvFullCanUse = convertView.findViewById(R.id.tv_full_can_use); holder.tvBeginAndOver = convertView.findViewById(R.id.tv_begin_and_over); holder.tvSource = convertView.findViewById(R.id.tv_source); holder.btnStateNotUsed = convertView.findViewById(R.id.btn_state_not_used); holder.btnStateUsed = convertView.findViewById(R.id.btn_state_used); holder.btnStateExpired = convertView.findViewById(R.id.btn_state_expired); holder.rlFoldLine = convertView.findViewById(R.id.rl_fold_line); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.tvPrice.setText(StringUtils.NullToStr(mList.get(position).getPrice())); holder.tvBeginAndOver.setText(StringUtils.NullToStr(mList.get(position).getBeginAndOver())); holder.tvFullCanUse.setText(StringUtils.NullToStr(mList.get(position).getFullCanUse())); holder.tvSource.setText(StringUtils.NullToStr(mList.get(position).getSource())); //区分 switch (StringUtils.NullToStr(mList.get(position).getState())) { case "0": //显示 holder.btnStateNotUsed.setVisibility(View.VISIBLE); holder.btnStateUsed.setVisibility(View.GONE); holder.btnStateExpired.setVisibility(View.GONE); //价格 holder.tvPrice.setTextColor(mContext.getResources().getColor(R.color.cs_FF5353)); //元 holder.tvElement.setTextColor(mContext.getResources().getColor(R.color.cs_FF5353)); //满减 holder.tvFullCanUse.setTextColor(mContext.getResources().getColor(R.color.cs_484848)); //有效 holder.tvBeginAndOver.setTextColor(mContext.getResources().getColor(R.color.cs_999999)); //折行 holder.rlFoldLine.setBackground(mContext.getResources().getDrawable(R.mipmap.ic_coupons_red)); //折行文字 holder.tvSource.setTextColor(mContext.getResources().getColor(R.color.white)); break; case "1": holder.btnStateUsed.setVisibility(View.VISIBLE); holder.btnStateNotUsed.setVisibility(View.GONE); holder.btnStateExpired.setVisibility(View.GONE); holder.tvPrice.setTextColor(mContext.getResources().getColor(R.color.cs_cccccc)); holder.tvElement.setTextColor(mContext.getResources().getColor(R.color.cs_cccccc)); holder.tvFullCanUse.setTextColor(mContext.getResources().getColor(R.color.cs_cccccc)); holder.tvBeginAndOver.setTextColor(mContext.getResources().getColor(R.color.cs_cccccc)); holder.rlFoldLine.setBackground(mContext.getResources().getDrawable(R.mipmap.ic_coupons_gray)); holder.tvSource.setTextColor(mContext.getResources().getColor(R.color.white)); break; case "2": holder.btnStateExpired.setVisibility(View.VISIBLE); holder.btnStateNotUsed.setVisibility(View.GONE); holder.btnStateUsed.setVisibility(View.GONE); holder.tvPrice.setTextColor(mContext.getResources().getColor(R.color.cs_cccccc)); holder.tvElement.setTextColor(mContext.getResources().getColor(R.color.cs_cdcdcd)); holder.tvFullCanUse.setTextColor(mContext.getResources().getColor(R.color.cs_cccccc)); holder.tvBeginAndOver.setTextColor(mContext.getResources().getColor(R.color.cs_cccccc)); holder.rlFoldLine.setBackground(mContext.getResources().getDrawable(R.mipmap.ic_coupons_gray)); holder.tvSource.setTextColor(mContext.getResources().getColor(R.color.white)); break; default: break; } holder.llAll.setOnClickListener(v -> { switch (StringUtils.NullToStr(mList.get(position).getState())) { case "0": Tt.showShort(mContext, "使用后走刷新接口"); break; case "1": Tt.showShort(mContext, "已使用优惠券不可点击"); break; case "2": Tt.showShort(mContext, "已过期优惠券不可点击"); break; default: break; } }); return convertView; } private class ViewHolder { /** * 整体 ,价格,元,满多少可以用,日期,来源,状态(3),折行 **/ private LinearLayout llAll; private TextView tvPrice; private TextView tvElement; private TextView tvFullCanUse; private TextView tvBeginAndOver; private MoreTextView tvSource; private Button btnStateNotUsed; private ImageButton btnStateUsed, btnStateExpired; private RelativeLayout rlFoldLine; } }
适配器子项布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:more="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/cs_F0F5FA" tools:ignore="DisableBaselineAlignment"> <!--我的优惠券子项布局--> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/ds_12dp" android:layout_marginLeft="@dimen/ds_14dp" android:layout_marginRight="@dimen/ds_14dp" tools:ignore="UselessParent"> <LinearLayout android:id="@+id/ll_all" android:layout_width="match_parent" android:layout_height="@dimen/ds_100dp" android:background="@drawable/part_top_white_round" tools:ignore="UselessParent"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="@dimen/ds_20dp" android:layout_marginRight="@dimen/ds_16dp" android:layout_weight="1" tools:ignore="InefficientWeight,RtlHardcoded"> <!--价格--> <TextView android:id="@+id/tv_price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0" android:textColor="@color/cs_FF5353" android:textSize="@dimen/ds_33sp" tools:ignore="HardcodedText" /> <TextView android:id="@+id/tv_element" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/tv_price" android:layout_toRightOf="@+id/tv_price" android:text="元" android:textColor="@color/cs_FF5353" android:textSize="@dimen/ds_16sp" tools:ignore="HardcodedText" /> <TextView android:id="@+id/tv_full_can_use" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/tv_price" android:layout_marginLeft="@dimen/ds_10dp" android:layout_toRightOf="@+id/tv_element" android:ellipsize="end" android:maxLines="1" android:text="满0元可用" android:textColor="@color/cs_484848" android:textSize="@dimen/ds_13sp" tools:ignore="HardcodedText" /> <!--未用--> <Button android:id="@+id/btn_state_not_used" android:layout_width="@dimen/ds_73dp" android:layout_height="@dimen/ds_27dp" android:layout_alignBaseline="@id/tv_price" android:layout_alignParentRight="true" android:background="@drawable/bg_red_round_small" android:text="使用" android:textColor="@color/cs_f28b84" android:visibility="gone" tools:ignore="HardcodedText,RtlHardcoded" /> <!--时间--> <TextView android:id="@+id/tv_begin_and_over" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/tv_price" android:text="有效期 2018-10-1~2018-12-11" android:textColor="@color/cs_999999" android:textSize="@dimen/ds_12sp" tools:ignore="HardcodedText" /> </RelativeLayout> <!--已用--> <ImageButton android:id="@+id/btn_state_used" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginRight="@dimen/ds_16dp" android:background="@mipmap/ic_coupons_us" android:visibility="gone" tools:ignore="ContentDescription,RtlHardcoded" /> <!--过期--> <ImageButton android:id="@+id/btn_state_expired" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginRight="@dimen/ds_16dp" android:background="@mipmap/ic_coupons_expired" android:visibility="gone" tools:ignore="ContentDescription,RtlHardcoded" /> </LinearLayout> <!--下部粉红色折行--> <RelativeLayout android:id="@+id/rl_fold_line" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/ll_all" android:background="@mipmap/ic_coupons_red"> <!--来源--> <com.yc.hospital.myview.MoreTextView android:id="@+id/tv_source" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_marginBottom="@dimen/ds_10dp" android:layout_marginLeft="@dimen/ds_19dp" android:layout_marginRight="@dimen/ds_19dp" android:layout_marginTop="@dimen/ds_10dp" more:maxLine="1" more:textColor="@color/white" more:textSize="@dimen/ds_12sp" tools:ignore="RtlHardcoded" /> </RelativeLayout> </RelativeLayout> </RelativeLayout>
子项布局效果图:
自定义控件(核心)
package com.yc.hospital.myview; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; import android.view.animation.Animation; import android.view.animation.RotateAnimation; import android.view.animation.Transformation; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import com.yc.hospital.R; /** * ================================================ * * @author:Vip 版 本:V 1.0.0 * 创建日期:2018/12/14 * 描 述:多行折叠自定义控件(适用于我的优惠劵页面) * 修订历史: * ================================================ */ public class MoreTextView extends RelativeLayout { /** * 文本及按钮 **/ protected TextView contentView; protected ImageView expandView; /** * 对应styleable中的属性 **/ protected int textColor; protected float textSize; protected int maxLine; protected String text; /** * 默认属性值 **/ public int defaultTextColor = Color.BLACK; public int defaultTextSize = 12; public int defaultLine = 1; public MoreTextView(Context context, AttributeSet attrs) { super(context, attrs); initView(); initWithAttrs(context, attrs); bindListener(); } /** * 初始化 **/ protected void initView() { //文案 contentView = new TextView(getContext()); RelativeLayout.LayoutParams tp = new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); tp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 16); tp.setMargins(16, 10, 40, 10); addView(contentView, tp); //箭头 expandView = new ImageView(getContext()); expandView.setBackground(getResources().getDrawable(R.mipmap.ic_whtie_triangle)); RelativeLayout.LayoutParams llp = new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); llp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 16); addView(expandView, llp); } protected void initWithAttrs(Context context, AttributeSet attrs) { @SuppressLint("CustomViewStyleable") TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MoreTextStyle); //取颜色值,默认defaultTextColor int textColor = a.getColor(R.styleable.MoreTextStyle_textColor, defaultTextColor); //取颜字体大小,默认defaultTextSize textSize = a.getDimensionPixelSize(R.styleable.MoreTextStyle_textSize, defaultTextSize); //取颜显示行数,默认defaultLine maxLine = a.getInt(R.styleable.MoreTextStyle_maxLine, defaultLine); //取文本内容 text = a.getString(R.styleable.MoreTextStyle_text); //绑定到textView bindTextView(textColor, textSize, maxLine, text); //回收释放 a.recycle(); } /** * 信息来源文案 **/ protected void bindTextView(int color, float size, final int line, String text) { contentView.setTextColor(color); contentView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); contentView.setText(text); contentView.setHeight(contentView.getLineHeight() * line); post(() -> expandView.setVisibility(contentView.getLineCount() > line ? View.VISIBLE : View.GONE)); } /** * 点击展开与折叠 **/ protected void bindListener() { setOnClickListener(new View.OnClickListener() { boolean isExpand; @Override public void onClick(View v) { //内容大于1行 if (contentView.getLineCount() > 1) { isExpand = !isExpand; contentView.clearAnimation(); final int deltaValue; final int startValue = contentView.getHeight(); int durationMillis = 350; if (isExpand) { final float[] nowTime = {0}; deltaValue = contentView.getLineHeight() * contentView.getLineCount() - startValue; RotateAnimation animation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animation.setDuration(durationMillis); animation.setFillAfter(true); expandView.startAnimation(animation); Animation animation1 = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { nowTime[0] = interpolatedTime; //改变文本的高度,多行展开 contentView.setHeight((int) (startValue + deltaValue * nowTime[0]) + 20); } }; animation1.setDuration(durationMillis); contentView.startAnimation(animation1); } else { final float[] nowTime = {0}; deltaValue = contentView.getLineHeight() * maxLine - startValue; RotateAnimation animation = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animation.setDuration(durationMillis); animation.setFillAfter(true); expandView.startAnimation(animation); Animation animation2 = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { //改变文本的高度,多行收缩 nowTime[0] = interpolatedTime; contentView.setHeight((int) (startValue + deltaValue * nowTime[0])); } }; animation2.setDuration(durationMillis); contentView.startAnimation(animation2); } } else { //只有一条 contentView.setPadding(0, 0, 0, 0); } } }); } public TextView getTextView() { return contentView; } public void setText(CharSequence charSequence) { contentView.setText(charSequence); } public void setTextColor(int color) { contentView.setTextColor(color); } public static int dip2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } }
attrs.xml:
<!--自定义多行折叠控件--> <declare-styleable name="MoreTextStyle"> <attr name="textSize" format="dimension" /> <attr name="textColor" format="color" /> <attr name="maxLine" format="integer" /> <attr name="text" format="string" /> </declare-styleable>
结尾:
上述就是全部功能了。 图片和颜色值就不提供了。可以在网上找图片替换,或者美工提供,或者自己写个背景色试验下。
我应该没有再漏下什么东西了。还有StringUtils工具类,我就是做了下非空,大家可以自行替换,胆大的可以不判断。。。toast工具类也是封装了下,用官方的toast也可以。再有就是当初是studio3.0开发的,jdk是1.8,里面有几行用了1.8新属性的链式表达式,看着不顺手的话,大家也可以按常规写法替换回来,有不明白的给我留言。博主活跃着,不会突然失踪。
补充:
1.我的这个列表,箭头区域是能折叠的,默认显示一行,超过一行箭头显示,点击有动画效果,不生硬,箭头旋转显示两行,再点复位。
2.为了大家理解方便,去掉了网络请求部分,及下拉刷新及分页。数据也以标准json格式处理及赋值。
3.应粉丝需求,写了一个demo,大家可以去我的资源里下载。