公司要求做这么一个列表展示可以输入的EditText一个listView的列表,有点像钉钉的物品采购模块,并且价格需要自动计算,数量乘以单价,上图所示的类似效果图,点击添加按钮可以新增一组条目用于填写,删除按钮可以删除一组条目。下面直接展示主要逻辑部分代码。时间部分在demo里面忽略掉了。可以用自己喜欢的时间框架.
首先是Activity的布局文件:mListView 是一项目中常用的和ScroolView嵌套的ListView布局,也可以用 RecylerView 代替
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@color/white">
<RelativeLayout
android:id="@+id/rl_back"
android:layout_width="48dp"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/icon_left_back"/>
</RelativeLayout>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Title"
android:textColor="#333333"
android:textSize="16sp"/>
<RelativeLayout
android:id="@+id/rl_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp"
>
<TextView
android:id="@+id/tv_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="right"
android:textColor="#333333" />
</RelativeLayout>
</RelativeLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<com.lzy.demoedittextinput.mListView
android:id="@+id/lv_goods_purchase"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:divider="@null"
android:scrollbars="none"/>
</ScrollView>
<TextView
android:id="@+id/tv_commit"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="@color/white"
android:gravity="center"
android:text="+ 新增物品"
android:textColor="#000"
android:textSize="16sp"/>
</LinearLayout>
下面是Activity代码,记得在清单文件注册。
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.alibaba.fastjson.JSON;
import java.util.ArrayList;
import java.util.List;
public class GoodsPurchaseParticularsActivity extends AppCompatActivity implements View.OnClickListener {
private List<GoodsPurchaseEntity> mList = new ArrayList<>();
private CreateGoodsPurChaseAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_goods_purchase_particulars);
String article_purchase = getIntent().getStringExtra("article_purchase");
if (article_purchase != null) {
mList = JSON.parseArray(article_purchase, GoodsPurchaseEntity.class);
} else {
mList.add(new GoodsPurchaseEntity());
}
mAdapter = new CreateGoodsPurChaseAdapter(this, mList);
RelativeLayout rl_back = (RelativeLayout) findViewById(R.id.rl_back);
TextView tv_title = (TextView) findViewById(R.id.tv_title);
ListView lv_goods_purchase = (ListView) findViewById(R.id.lv_goods_purchase);
TextView tv_commit = (TextView) findViewById(R.id.tv_commit);
RelativeLayout rl_right = (RelativeLayout) findViewById(R.id.rl_right);
TextView tv_right = (TextView) findViewById(R.id.tv_right);
tv_title.setText("明细");
tv_right.setText("确定");
mList.add(new GoodsPurchaseEntity());
rl_back.setOnClickListener(this);
tv_commit.setOnClickListener(this);
rl_right.setOnClickListener(this);
lv_goods_purchase.setAdapter(mAdapter);
mAdapter.setOnDeleteItemListener(new CreateGoodsPurChaseAdapter.onDeleteItemListener() {
@Override
public void deleteItemListener(int position) {
mList.remove(position);
mAdapter.notifyDataSetChanged();
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.rl_back:
finish();
break;
case R.id.tv_commit:
mList.add(new GoodsPurchaseEntity());
mAdapter.notifyDataSetChanged();
break;
case R.id.rl_right:
submit();
break;
}
}
private void submit() {
for (int i = 0; i < mList.size(); i++) {
String norms = mList.get(i).getNorms();
String name = mList.get(i).getName();
String num = mList.get(i).getNum();
String units = mList.get(i).getUnits();
String type = mList.get(i).getType();
String unit_price = mList.get(i).getUnit_price();
String all_price = mList.get(i).getAll_price();
if (TextUtils.isEmpty(norms) || TextUtils.isEmpty(name) || TextUtils.isEmpty(num)
|| TextUtils.isEmpty(units) || TextUtils.isEmpty(type)
|| TextUtils.isEmpty(unit_price) || TextUtils.isEmpty(all_price)) {
Toast.makeText(this, "明细填写不全", Toast.LENGTH_SHORT).show();
return;
}
}
Double all_price = 0.00;
String goods = JSON.toJSONString(mList);
for (int i = 0; i < mList.size(); i++) {
Double all_prices = Double.parseDouble(mList.get(i).getAll_price());
all_price = all_price + all_prices;
}
Intent intent = new Intent();
intent.putExtra("all_price", all_price + "");
intent.putExtra("article_purchase", goods);
intent.putExtra("num", mList.size() + "");
setResult(RESULT_OK, intent);
finish();
}
public void saveEditData(int position, String type, String str) {
//数字用于区分EditText
try {
if ("1".equals(type)) {
mList.get((position - 1) / 100).setType(str);
} else if ("2".equals(type)) {
mList.get((position - 2) / 100).setName(str);
} else if ("3".equals(type)) {
mList.get((position - 3) / 100).setNorms(str);
} else if ("4".equals(type)) {
mList.get((position - 4) / 100).setNum(str);
} else if ("5".equals(type)) {
mList.get((position - 5) / 100).setUnits(str);
} else if ("6".equals(type)) {
mList.get((position - 6) / 100).setUnit_price(str);
} else if ("7".equals(type)) {
mList.get((position - 7) / 100).setAll_price(str);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
下面是适配器代码,布局文件在后面。因为listView 先绘制的特性,所以思路是将EditText 的输入的值以监听的方式存入到实体中。
import android.content.Context;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.text.DecimalFormat;
import java.util.List;
public class CreateGoodsPurChaseAdapter extends BaseAdapter {
private Context mContext;
private List<GoodsPurchaseEntity> mList;
private onDeleteItemListener mOnDeleteItemListener;
private final DecimalFormat mFormat;
public CreateGoodsPurChaseAdapter(Context context, List<GoodsPurchaseEntity> list) {
mContext = context;
mList = list;
mFormat = new DecimalFormat("##.##");
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_goods_purchase, null);
holder = new ViewHolder(convertView, position);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (position == 0) {
holder.tv_delete.setVisibility(View.GONE);
// holder.tv_num.setText("采购明细");
} else {
holder.tv_delete.setVisibility(View.VISIBLE);
}
int i = position + 1;
holder.tv_num.setText("采购明细(" + i + ")");
holder.rl_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnDeleteItemListener.deleteItemListener(position);
}
});
holder.et_type.setTag(position * 100 + 1);
holder.et_name.setTag(position * 100 + 2);
holder.et_norms.setTag(position * 100 + 3);
holder.et_num.setTag(position * 100 + 4);
holder.et_units.setTag(position * 100 + 5);
holder.et_unit_price.setTag(position * 100 + 6);
holder.tv_all_price.setTag(position * 100 + 7);
GoodsPurchaseEntity bean = mList.get(position);
holder.et_type.setText(bean.getType());
holder.et_name.setText(bean.getName());
holder.et_norms.setText(bean.getNorms());
holder.et_num.setText(bean.getNum());
holder.et_units.setText(bean.getUnits());
holder.et_unit_price.setText(bean.getUnit_price());
holder.tv_all_price.setText(bean.getAll_price());
return convertView;
}
class ViewHolder {
private TextView tv_delete;
private RelativeLayout rl_delete;
private EditText et_type;
private EditText et_name;
private EditText et_norms;
private EditText et_num;
private EditText et_units;
private EditText et_unit_price;
private TextView tv_all_price;
private TextView tv_num;
public ViewHolder(View convertView, int position) {
tv_delete = (TextView) convertView.findViewById(R.id.tv_delete);
tv_num = (TextView) convertView.findViewById(R.id.tv_num);
tv_all_price = (TextView) convertView.findViewById(R.id.tv_all_price);
rl_delete = (RelativeLayout) convertView.findViewById(R.id.rl_delete);
et_type = (EditText) convertView.findViewById(R.id.et_type);
et_name = (EditText) convertView.findViewById(R.id.et_name);
et_norms = (EditText) convertView.findViewById(R.id.et_norms);
et_num = (EditText) convertView.findViewById(R.id.et_num);
et_units = (EditText) convertView.findViewById(R.id.et_units);
et_unit_price = (EditText) convertView.findViewById(R.id.et_unit_price);
et_type.addTextChangedListener(new TextSwitcher(this, "1"));
et_name.addTextChangedListener(new TextSwitcher(this, "2"));
et_norms.addTextChangedListener(new TextSwitcher(this, "3"));
et_num.addTextChangedListener(new TextSwitcher(this, "4"));
et_units.addTextChangedListener(new TextSwitcher(this, "5"));
et_unit_price.addTextChangedListener(new TextSwitcher(this, "6"));
tv_all_price.addTextChangedListener(new TextSwitcher(this, "7"));
}
}
class TextSwitcher implements TextWatcher {
private ViewHolder mHolder;
private String mType;
public TextSwitcher(ViewHolder mHolder, String type) {
this.mHolder = mHolder;
mType = type;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if ("1".equals(mType)) {
int position = (Integer) mHolder.et_type.getTag();
((GoodsPurchaseParticularsActivity) mContext).saveEditData(position, mType, s.toString());
} else if ("2".equals(mType)) {
int position = (Integer) mHolder.et_name.getTag();
((GoodsPurchaseParticularsActivity) mContext).saveEditData(position, mType, s.toString());
} else if ("3".equals(mType)) {
int position = (Integer) mHolder.et_norms.getTag();
((GoodsPurchaseParticularsActivity) mContext).saveEditData(position, mType, s.toString());
} else if ("4".equals(mType)) {
int position = (Integer) mHolder.et_num.getTag();
((GoodsPurchaseParticularsActivity) mContext).saveEditData(position, mType, s.toString());
String et_num = mHolder.et_num.getText().toString();
String units_price = mHolder.et_unit_price.getText().toString();
if (TextUtils.isEmpty(et_num) || TextUtils.isEmpty(units_price)) {
mHolder.tv_all_price.setText("0");
} else {
double all_price = Double.parseDouble(et_num) * Double.parseDouble(units_price);
String formatted = mFormat.format(all_price);
mHolder.tv_all_price.setText(formatted + "");
}
} else if ("5".equals(mType)) {
int position = (Integer) mHolder.et_units.getTag();
((GoodsPurchaseParticularsActivity) mContext).saveEditData(position, mType, s.toString());
} else if ("6".equals(mType)) {
int position = (Integer) mHolder.et_unit_price.getTag();
((GoodsPurchaseParticularsActivity) mContext).saveEditData(position, mType, s.toString());
String et_num = mHolder.et_num.getText().toString();
String units_price = mHolder.et_unit_price.getText().toString();
if (TextUtils.isEmpty(et_num) || TextUtils.isEmpty(units_price)) {
mHolder.tv_all_price.setText("0");
} else {
double all_price = Double.parseDouble(et_num) * Double.parseDouble(units_price);
String formatted = mFormat.format(all_price);
mHolder.tv_all_price.setText(formatted + "");
}
} else if ("7".equals(mType)) {
if (mHolder.tv_all_price.getTag() != null) {
int position = (Integer) mHolder.tv_all_price.getTag();
((GoodsPurchaseParticularsActivity) mContext).saveEditData(position, mType, s.toString());
}
}
}
}
public interface onDeleteItemListener {
void deleteItemListener(int position);
}
public void setOnDeleteItemListener(onDeleteItemListener onDeleteItemListener) {
mOnDeleteItemListener = onDeleteItemListener;
}
}
下面是适配器Item布局,为了节省代码,封装了style
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/rl_delete"
android:layout_width="match_parent"
android:layout_height="30dp"
>
<TextView
android:id="@+id/tv_num"
android:layout_width="wrap_content"
android:layout_marginLeft="15dp"
android:gravity="center"
android:text="报销明细"
android:textSize="12sp"
android:textColor="#999999"
android:layout_height="match_parent"/>
<TextView
android:id="@+id/tv_delete"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:gravity="center_vertical"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:text="删除"
android:textColor="#32a8fc"
android:textSize="12sp"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:orientation="horizontal">
<TextView
android:text="采购类型"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:gravity="center"
android:textColor="#666666"/>
<EditText
android:id="@+id/et_type"
android:hint="请输入"
style="@style/common_45dp_edittext"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:background="#e5e5e5"
android:layout_height="0.5dp"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="45dp">
<TextView
android:text="物品名称"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:gravity="center"
android:textColor="#666666"/>
<EditText
android:id="@+id/et_name"
android:hint="请输入"
style="@style/common_45dp_edittext"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:background="#e5e5e5"
android:layout_height="0.5dp"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="45dp">
<TextView
android:text="规格 "
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:gravity="center"
android:textColor="#666666"/>
<EditText
android:id="@+id/et_norms"
android:hint="请输入"
style="@style/common_45dp_edittext"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:background="#e5e5e5"
android:layout_height="0.5dp"/>
<LinearLayout
style="@style/common_45dp_linearLayout">
<TextView
android:text="数量 "
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:gravity="center"
android:textColor="#666666"/>
<EditText
android:id="@+id/et_num"
android:hint="请输入"
android:inputType="number"
style="@style/common_45dp_edittext"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:background="#e5e5e5"
android:layout_height="0.5dp"/>
<LinearLayout
style="@style/common_45dp_linearLayout">
<TextView
android:text="单位 "
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:gravity="center"
android:textColor="#666666"/>
<EditText
android:id="@+id/et_units"
android:hint="请输入"
style="@style/common_45dp_edittext"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:background="#e5e5e5"
android:layout_height="0.5dp"/>
<LinearLayout
style="@style/common_45dp_linearLayout">
<TextView
android:text="单价 "
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:gravity="center"
android:textColor="#666666"/>
<EditText
android:id="@+id/et_unit_price"
android:hint="请输入"
android:inputType="numberDecimal"
style="@style/common_45dp_edittext"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:background="#e5e5e5"
android:layout_height="0.5dp"/>
<LinearLayout
style="@style/common_45dp_linearLayout">
<TextView
android:text="总价 "
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:gravity="center"
android:textColor="#666666"/>
<TextView
android:id="@+id/tv_all_price"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_weight="1"
android:background="@null"
android:gravity="center_vertical"
android:hint="0"
android:textColor="#333333"
android:textColorHint="#999999"
/>
</LinearLayout>
</LinearLayout>
style 如下
<!-- 通用45dp #111 文字,提示文字#999 主要用于文字填写-->
<style name="common_45dp_edittext">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<item name="android:layout_marginLeft">10dp</item>
<item name="android:background">@null</item>
<item name="android:singleLine">true</item>
<item name="android:textColor">#333333</item>
<item name="android:textColorHint">#999999</item>
<item name="android:textSize">14sp</item>
</style>
<!-- 通用45dp 白底 条目线性布局 主要用于条目选择-->
<style name="common_45dp_linearLayout">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">45dp</item>
<item name="android:gravity">center_vertical</item>
<item name="android:orientation">horizontal</item>
</style>
以上就是这个需求的主题逻辑和思路,如果有问题希望大家指正,也希望和有其他思路的大神交流学习。↖(▔.▔)↗