2017-09-19 10:28:10 gxp1182893781 阅读数 1048

有的时候我们的项目是需要拼接图片的,怎么实现呢?

直接上代码:

/**
 * 横向拼接图片
 * <功能详细描述>
 *
 * @param first
 * @param second
 * @return
 */
public static final Bitmap splitHorizontal(Bitmap first, Bitmap second) {
    int width = first.getWidth() + second.getWidth();
    int height = Math.max(first.getHeight(), second.getHeight());
    Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    canvas.drawBitmap(first, 0, 0, null);
    canvas.drawBitmap(second, first.getWidth(), 0, null);
    return result;
}


/**
 * 纵向拼接图片
 * <功能详细描述>
 *
 * @param first
 * @param second
 * @return
 */
public static Bitmap splitVertical(Bitmap first, Bitmap second) {
    int width = Math.max(first.getWidth(), second.getWidth());
    int height = first.getHeight() + second.getHeight();
    Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    canvas.drawBitmap(first, 0, 0, null);
    canvas.drawBitmap(second, 0, first.getHeight(), null);
    return result;
}

调用的时候按照顺序传入两张图片的bitmap就可以了,简单方便。

如果两张bitmap宽高无法匹配,可以使用以下代码进行伸缩,其中的第2,3个参数是伸缩后的宽和高。

Bitmap bitmap1 = Bitmap.createScaledBitmap(bitmap,430,430,true);

你也可以使用以下代码通过设置伸缩比例来创建bitmap

// 获得屏幕宽度
int secreenWidth = getWindowManager().getDefaultDisplay().getWidth();
// 计算缩放比例
float scaleWidth = ((float) secreenWidth) / bitmapWidth;
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleWidth);
Bitmap visiableBitmap = Bitmap.createBitmap(result, 0, 0, result.getWidth(),
        result.getHeight(), matrix, true);
其中的result是原始的图片,我想要把图片的尺寸伸缩为宽度和屏幕宽度一致。






2018-01-04 14:51:56 qq_27688259 阅读数 239

在android开发中通常http请求,文件上传都交由成熟框架实现,这样是十分正确的行为,但是由于某些特殊的需求问题,仍需掌握最原始的http报文的自定义拼接,才能完成这些特殊的需求。如存在问题使用Fiddler4抓包与后台分析报文区别修改即可。

package com.smarthome.anbao.utils;
import android.text.TextUtils;
import com.Player.web.websocket.ClientCore;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;

/**
 * Created by 袁祖强 on 2017/7/18.
 */
public class UploadFileUtil {
    private String url;
    private Map<String, String> headParams;
    private Map<String, String> params;
    private List<String> files;
    private UploadFileListener uploadFileListener;
    public UploadFileUtil(String url,Map<String, String> headParams,Map<String, String> params,List<String> files,UploadFileListener uploadFileListener){
        this.url = url;
        this.headParams = headParams;
        this.params = params;
        this.files = files;
        this.uploadFileListener = uploadFileListener;
    }
    public void uploadDone(){
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    UploadFile();
                } catch (IOException e) {
                    uploadFileListener.uploadError(e.toString());
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }
    public  void UploadFile() throws IOException {
        String BOUNDARY = java.util.UUID.randomUUID().toString();
        String PREFIX = "--", LINEND = "\r\n";
        String MULTIPART_FROM_DATA = "multipart/form-data";//提交方式,二进制表单提交
        String CHARSET = "UTF-8";

        URL uri = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
        conn.setReadTimeout(30 * 1000); // 缓存的最长时间
        conn.setDoInput(true);// 允许输入
        conn.setDoOutput(true);// 允许输出
        conn.setUseCaches(false); // 不允许使用缓存
        conn.setRequestMethod("POST");
        conn.setRequestProperty("connection", "keep-alive");
        conn.setRequestProperty("Charsert", "UTF-8");
        conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);
        uploadFileListener.uploadStart();
        if(headParams != null){
            for(String key : headParams.keySet()){
                conn.setRequestProperty(key, headParams.get(key));
            }
        }
        StringBuilder sb = new StringBuilder();
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                sb.append(PREFIX);
                sb.append(BOUNDARY);
                sb.append(LINEND);
                sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);
                sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);
                sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
                sb.append(LINEND);
                sb.append(entry.getValue());
                sb.append(LINEND);
            }
        }

        DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());//获取输出流
        if (!TextUtils.isEmpty(sb.toString())) {
            outStream.write(sb.toString().getBytes());
        }

        if (files.size() > 0)
            for (int i = 0 ; i < files.size() ; i++) {
                File file = new File(files.get(i));
                StringBuilder sb1 = new StringBuilder();
                sb1.append(PREFIX);
                sb1.append(BOUNDARY);
                sb1.append(LINEND);
                sb1.append("S:" + ClientCore.SESSION_ID + LINEND);//添加session 校验
                sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"" + LINEND);
                sb1.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINEND);
                sb1.append(LINEND);
                outStream.write(sb1.toString().getBytes());
                InputStream is = new FileInputStream(file);
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = is.read(buffer)) != -1) {
                    outStream.write(buffer, 0, len);
                }
                is.close();
                outStream.write(LINEND.getBytes());
            }

        // 请求结束标志
        byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
        outStream.write(end_data);
        outStream.flush();
        // 得到响应码
        int res = conn.getResponseCode();
        InputStream in = conn.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
        StringBuffer buffer = new StringBuffer();
        String line = "";
        while ((line = bufferedReader.readLine()) != null){
            buffer.append(line);
        }
        if (res == 200) {
            uploadFileListener.uploadFinish(buffer.toString());
        }else{
            uploadFileListener.uploadError(in.toString());
        }
        outStream.close();
        conn.disconnect();
    }
}
2017-07-27 13:58:30 shaoyezhangliwei 阅读数 3531

不知道各位小伙伴在开发应用客户端的时候有没有碰到过这样的需求,就是需要在app端维护大量的表数据。

一般的应用可能需要客户端上传数据的时候 就几张表或者几个功能,但是大量的表格就很复杂。

举列:我们碰到的需求是 维护表格数据 ,这些表格都是政府部门的一些表格文件,而且非常多,一个轨道系统有将近400张表格。对  是400多张,而且没有任何规律,字段什么的都不一样,在之前有个房建系统做了大概几十张,之前的小伙伴是写了几十个activity... 但是这次400张怎么处理?

如图下面的表格:

 

 

 

类似上面的表格,400多个,都要可以实现在app端填写,然后上传到服务器。

 

app端最后实现效果(手机比较小,截图搞了很多张,gif做出来都太大,传不上来,大概意思能看)

 

 

 

界面不美观,凑合看吧...说重点..

 

实现的整体思路:

 

1.处理 400张表的数据 

 

将400张表的字段存到一张表里面,整理这400张表的数据是个比较大的工作,我们有个做delphi的工程师专门做了一个配置工具,打开每张表配置这张表格的字段。

数据库主要包括4张表格:T_Table  存储所有表格数据  T_TableDetail 存储所有表的字段数据 T_Type 字典表  存储所有控件类型  T_DIC存储所有表下拉数据

T_Table  字段包括:id  name  order parentID(因为我们这个表显示有层级结构)  

T_TableDetail字段主要包括 :字段id   字段名称  字段顺序   表格id(属于哪张表)    类型id(这个字段要用什么控件显示)  isRequired 是否必填 defaultValue默认值 

row   col  行列   dicid关联字典表数据

核心的就这些   这个根据自己的具体业务再搭建自己的数据库表结构。
 

2.搭建界面

有了基础数据后,我们要做的就是写一个通用Activity去动态拼装整个界面 

我实现的思路是这样的 :将每种类型的控件都单独写成xml,比如有15种类型的控件就写15个xml,根据字段类型判断加载哪种类型的xml。

判断加载完界面  处理界面控件设置默认值,设置点击事件,设置是否可以编辑点击等(因为查看  修改  添加都用一套界面),这一些基本逻辑。

 

我就直接将初始化布局的地方贴出来,大家看一下。

 

public class ViewTypeUtil {
	
	//表格名称类型 输入框  默认带值 且要单独获取值
    public static final int item_view_type_zero = 0;
    //单行输入框
    public static final int item_view_type_one = 1;
    //多行输入框
    public static final int item_view_type_two = 2;
    //短日期 如2012-01-12
    public static final int item_view_type_three = 3;
    //数值
    public static final int item_view_type_four = 4;
    //下拉框
    public static final int item_view_type_five = 5;
    //分部分项
    public static final int item_view_type_six = 6;
    //部位栏
    public static final int item_view_type_seven = 7;
    //单选框
    public static final int item_view_type_eight = 8;
    //多选框
    public static final int item_view_type_nine= 9;
    //列表
    public static final int item_view_type_ten = 10;
    //图纸标准
    public static final int item_view_type_eleven = 11;
    //图片
    public static final int item_view_type_twelve = 12;
    //组
    public static final int item_view_type_thirteen = 13;
    //长日期 2017-07-02 10:38:41
    public static final int item_view_type_fourteen  = 14;
    //时间格式 如 10:25:14
    public static final int item_view_type_fifteen  = 15;
    //标签
    public static final int item_view_type_sixteen  = 16;
    

}

 

 

 

 

 

 

	public void initView(final LinearLayout linearLayout, List<FormDetail> formDetailList) {
		for (int i = 0; i < formDetailList.size(); i++) {
			final FormDetail formDetail = formDetailList.get(i);
			final int mType = formDetail.getTypeId();
			if (mType == ViewTypeUtil.item_view_type_zero) {
				mTypeZeroView = LayoutInflater.from(this).inflate(R.layout.item_type_zero, null);
				mItemZeroFieldTv = (TextView) mTypeZeroView.findViewById(R.id.item_zero_field_tv);
				mItemZeroValueEt = (EditText) mTypeZeroView.findViewById(R.id.item_zero_value_et);
				if (mIntentFrom == FLAG_SHOW) {
					mItemZeroValueEt.setEnabled(false);
				}
				mItemZeroValueEt.setText(formDetail.getuValue());
				mItemZeroValueEt.setTag(formDetail.getTableDetailID());
				mItemZeroFieldTv.setText(formDetail.getCaption());
				mTypeZeroView.setTag(mType);
				linearLayout.addView(mTypeZeroView);

			} else if (mType == ViewTypeUtil.item_view_type_one) {
				mTypeOneView = LayoutInflater.from(this).inflate(R.layout.item_type_one, null);
				mItemOneFieldTv = (TextView) mTypeOneView.findViewById(R.id.item_one_field_tv);
				mItemOneValueEt = (EditText) mTypeOneView.findViewById(R.id.item_one_value_et);
				if (mIntentFrom == FLAG_SHOW) {
					mItemOneValueEt.setEnabled(false);
				}
				mItemOneValueEt.setText(formDetail.getuValue());
				mItemOneValueEt.setTag(formDetail.getTableDetailID());
				mItemOneFieldTv.setText(formDetail.getCaption());
				mTypeOneView.setTag(mType);
				linearLayout.addView(mTypeOneView);
			} else if (mType == ViewTypeUtil.item_view_type_two) {
				mTypeTwoView = LayoutInflater.from(this).inflate(R.layout.item_type_two, null);
				mItemTwoValueEt = (EditText) mTypeTwoView.findViewById(R.id.content_et);
				mItemTwoValueEt.setTypeface(Constants.fontFace);
				mItemTwoFieldTv = (TextView) mTypeTwoView.findViewById(R.id.item_two_field_tv);
				if (mIntentFrom == FLAG_SHOW) {
					mItemTwoValueEt.setEnabled(false);
				} else {
					mTypeTwoView.findViewById(R.id.content_iv).setOnClickListener(this);
					mTypeTwoView.findViewById(R.id.voice_iv).setOnClickListener(this);
					mTypeTwoView.findViewById(R.id.special_iv).setOnClickListener(this);
				}
				mItemTwoValueEt.setText(formDetail.getuValue());
				mItemTwoFieldTv.setText(formDetail.getCaption());
				mItemTwoValueEt.setTag(formDetail.getTableDetailID());
				mTypeTwoView.findViewById(R.id.voice_iv).setTag(formDetail.getTableDetailID());
				mTypeTwoView.findViewById(R.id.special_iv).setTag(formDetail.getTableDetailID());
				mTypeTwoView.findViewById(R.id.content_iv).setTag(formDetail.getTableDetailID());

				mTypeTwoView.setTag(mType);
				linearLayout.addView(mTypeTwoView);
			} else if (mType == ViewTypeUtil.item_view_type_three) {
				mTypeThreeView = LayoutInflater.from(this).inflate(R.layout.item_type_three, null);
				mDateKeyTv = (TextView) mTypeThreeView.findViewById(R.id.tv_test_date_key);
				mDateValueEt = (EditText) mTypeThreeView.findViewById(R.id.et_test_date_value);
				mDateKeyTv.setText(formDetail.getCaption());
				if (mIntentFrom == FLAG_SHOW) {
					mDateValueEt.setEnabled(false);
				} else {
					mDateValueEt.setOnClickListener(this);
				}
				if (!TextUtils.isEmpty(formDetail.getuValue())) {
					mDateValueEt.setText(formDetail.getuValue());
				} else {
					mDateValueEt.setText(TimeUtil.getCurDateStr().substring(0, 12));
				}
				mDateValueEt.setTag(formDetail.getTableDetailID());

				mTypeThreeView.setTag(mType);
				linearLayout.addView(mTypeThreeView);
			} else if (mType == ViewTypeUtil.item_view_type_four) {
				mTypeFourView = LayoutInflater.from(context).inflate(R.layout.item_type_four, null);
				mNumEt = (EditText) mTypeFourView.findViewById(R.id.et_num);
				mItemFourFieldTv = (TextView) mTypeFourView.findViewById(R.id.item_four_field_tv);
				mNumEt.setText(formDetail.getuValue());
				mNumEt.setTag(formDetail.getTableDetailID());
				mItemFourFieldTv.setText(formDetail.getCaption());
				if (mIntentFrom == FLAG_SHOW) {
					mNumEt.setEnabled(false);
				}
				mTypeFourView.setTag(mType);
				linearLayout.addView(mTypeFourView);
			} else if (mType == ViewTypeUtil.item_view_type_five) {
				mTypeFiveView = LayoutInflater.from(this).inflate(R.layout.item_type_five, null);
				mSelectKeyTv = (TextView) mTypeFiveView.findViewById(R.id.et_select_key);
				mSelectValueEt = (EditText) mTypeFiveView.findViewById(R.id.et_select_value);
				mSelectValueEt.setText(formDetail.getuValue());
				if (mIntentFrom == FLAG_SHOW) {
					mSelectValueEt.setEnabled(false);
				} else {
					mSelectValueEt.setOnClickListener(this);
				}
				mSelectKeyTv.setText(formDetail.getCaption());
				mSelectValueEt.setTag(R.id.select_view_position, i);
				mSelectValueEt.setTag(R.id.select_view_detial_id, formDetail.getTableDetailID());
				mTypeFiveView.setTag(mType);
				linearLayout.addView(mTypeFiveView);
			} else if (mType == ViewTypeUtil.item_view_type_six) {

			} else if (mType == ViewTypeUtil.item_view_type_seven) {// 部位栏
				mTypeSevenView = LayoutInflater.from(this).inflate(R.layout.item_type_seven, null);
				mPartSelectKeyTv = (TextView) mTypeSevenView.findViewById(R.id.tv_select_part_key);
				mPartSelectValueEt = (EditText) mTypeSevenView.findViewById(R.id.et_select_part_value);
				mPartSelectKeyTv.setText(formDetail.getCaption());
				mPartSelectValueEt.setText(formDetail.getuValue());
				if (mIntentFrom == FLAG_SHOW) {
					mPartSelectValueEt.setEnabled(false);
				} else {
					mPartSelectValueEt.setOnClickListener(this);
				}
				mPartSelectValueEt.setTag(formDetail.getTableDetailID());
				mTypeSevenView.setTag(mType);
				linearLayout.addView(mTypeSevenView);

			} else if (mType == ViewTypeUtil.item_view_type_eight) {// 单选框
				mTypeEightView = LayoutInflater.from(this).inflate(R.layout.item_type_eight, null);
				mTypeEightKeyTv = (TextView) mTypeEightView.findViewById(R.id.tv_type_eight_key);
				rgTypeEight = (RadioGroup) mTypeEightView.findViewById(R.id.rb_type_eight);
				mTypeEightKeyTv.setText(formDetail.getCaption());

				List<DicBean> dicBeans = formDetail.getDicBeanList();
				if (dicBeans == null) {
					return;
				}
				for (int j = 0; j < dicBeans.size(); j++) {
					RadioButton radioButton = new RadioButton(context);
					LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
					radioButton.setText(dicBeans.get(j).getDicName());
					radioButton.setTag(formDetail.getTableDetailID() + "," + dicBeans.get(j).getDicID());
					radioButton.setId(j);
					rgTypeEight.addView(radioButton, params);
					if (mIntentFrom == FLAG_SHOW) {// 查看
						radioButton.setEnabled(false);
						if ((dicBeans.get(j).getDicID() + "").equals(formDetail.getuValue())) {
							rgTypeEight.check(j);
						}
					} else if (mIntentFrom == FLAG_UPDATE) {// 修改
						radioButton.setEnabled(true);
						if ((dicBeans.get(j).getDicID() + "").equals(formDetail.getuValue())) {
							rgTypeEight.check(j);
						}
					} else {// 添加
						rgTypeEight.check(0);
						radioButton.setEnabled(true);
					}
				}
				mTypeEightView.setTag(mType);
				linearLayout.addView(mTypeEightView);
			} else if (mType == ViewTypeUtil.item_view_type_nine) {// 多选框
				mTypeNineView = LayoutInflater.from(this).inflate(R.layout.item_type_nine, null);
				mTypeNineKeyTv = (TextView) mTypeNineView.findViewById(R.id.tv_type_nine_key);// 没有用到
				cbxTypeNine = (CheckBox) mTypeNineView.findViewById(R.id.cbx_type_nine);
				cbxTypeNine.setText(formDetail.getCaption());
				cbxTypeNine.setTag(formDetail.getTableDetailID() + "," + formDetail.getDicID());
				cbxTypeNine.setOnClickListener(this);
				mTypeNineView.setTag(mType);
				linearLayout.addView(mTypeNineView);
			} else if (mType == ViewTypeUtil.item_view_type_ten) {// 列表
				final String detailId = formDetail.getTableDetailID();
				mTypeTenView = LayoutInflater.from(context).inflate(R.layout.item_type_ten, null);
				mTypeTenKeyTv = (TextView) mTypeTenView.findViewById(R.id.tv_type_ten_key);
				mTypeTenKeyTv.setText(formDetail.getCaption());
				mTypeTenLinearLayout = (LinearLayout) mTypeTenView.findViewById(R.id.ly_type_ten);
				mTypeTenLinearLayout.setTag(formDetail.getTableDetailID());
				mTypeTenView.setTag(mType);
				linearLayout.addView(mTypeTenView);
				new AsyncTask<Void, Void, Void>() {
					@Override
					protected Void doInBackground(Void... params) {
						if (mIntentFrom == FLAG_SHOW || mIntentFrom == FLAG_UPDATE) {// 查看,修改
							mFormDetailMap = GdjtUserDataDBOperation.getInstance().getChildListDetailValueData(mUTableID, formDetail.getTableDetailID());
						} else {// 添加
							mFormDetailChildList = GdjtFormDBOperation.getInstance().getChildListDetailData(formDetail.getTableDetailID());
						}
						return null;
					}

					@Override
					protected void onPostExecute(Void result) {
						if (mIntentFrom == FLAG_SHOW || mIntentFrom == FLAG_UPDATE) {
							mTypeTenView.findViewById(R.id.iv_type_ten_add).setVisibility(View.GONE);
							mTypeTenLinearLayout.setWeightSum(3.0f);
							ShowChildView();
						} else {
							AddListChildView();
							mTypeTenLinearLayout.setWeightSum(2.5f);
							mTypeTenView.findViewById(R.id.iv_type_ten_add).setVisibility(View.VISIBLE);
							mTypeTenView.findViewById(R.id.iv_type_ten_add).setOnClickListener(CommonFormViewActivity.this);
						}
					}
				}.execute();

			} else if (mType == ViewTypeUtil.item_view_type_eleven) {// 图纸标准
				mTypeElevenView = LayoutInflater.from(this).inflate(R.layout.item_type_eleven, null);
				mTypeElevenKeyTv = (TextView) mTypeElevenView.findViewById(R.id.tv_type_eleven_key);
				mDrawingNameTv = (TextView) mTypeElevenView.findViewById(R.id.item_eleven_value_et);
				mDrawingNameTv.setOnClickListener(this);
				mDrawingNameTv.setTag(formDetail.getTableDetailID());
				if (!TextUtils.isEmpty(mDrawingPath)) {
					mDrawingNameTv.setText(mDrawingPath.subSequence(mDrawingPath.lastIndexOf("/") + 1, mDrawingPath.length()));
				}
				mTypeElevenView.findViewById(R.id.item_eleven_value_img_photo).setOnClickListener(this);
				mTypeElevenView.findViewById(R.id.item_eleven_value_img_folder).setOnClickListener(this);
				mTypeElevenKeyTv.setText(formDetail.getCaption());
				mTypeElevenView.setTag(mType);
				linearLayout.addView(mTypeElevenView);
			} else if (mType == ViewTypeUtil.item_view_type_twelve) {// 图片
				mTypeTwelveView = LayoutInflater.from(this).inflate(R.layout.item_type_twelve, null);
				mTypeTwelveKeyTv = (TextView) mTypeTwelveView.findViewById(R.id.tv_type_twelve_key);
				mTypeTwelveValueTv = (TextView) mTypeTwelveView.findViewById(R.id.item_twelve_value_path);
				mTypeTwelveTakePhoto = mTypeTwelveView.findViewById(R.id.item_twelve_value_img_photo);
				mTypeTwelveSelectPhoto = mTypeTwelveView.findViewById(R.id.item_twelve_value_img_folder);
				if (mIntentFrom == FLAG_SHOW) {
					mTypeTwelveTakePhoto.setEnabled(false);
					mTypeTwelveSelectPhoto.setEnabled(false);
				} else {
					mTypeTwelveTakePhoto.setOnClickListener(this);
					mTypeTwelveSelectPhoto.setOnClickListener(this);
				}
				mTypeTwelveValueTv.setOnClickListener(this);
				mPhotoPath = formDetail.getuValue();
				mTypeTwelveKeyTv.setText(formDetail.getCaption());
				mTypeTwelveValueTv.setText(mPhotoPath.substring(mPhotoPath.lastIndexOf("/") + 1));
				mTypeTwelveValueTv.setTag(formDetail.getTableDetailID());
				mTypeTwelveTakePhoto.setTag(formDetail.getTableDetailID());
				mTypeTwelveSelectPhoto.setTag(formDetail.getTableDetailID());
				mTypeTwelveView.setTag(mType);
				linearLayout.addView(mTypeTwelveView);
			} else if (mType == ViewTypeUtil.item_view_type_thirteen) {// 组
				final String detailId = formDetail.getTableDetailID();
				mTypeThirteenView = LayoutInflater.from(context).inflate(R.layout.item_type_thirteen, null);
				mTypeThirteenKeyTv = (TextView) mTypeThirteenView.findViewById(R.id.tv_type_thirteen_key);
				mTypeThirteenKeyTv.setText(formDetail.getCaption());
				mTypeThirteenLinearLayout = (LinearLayout) mTypeThirteenView.findViewById(R.id.ly_type_thirteen);
				mTypeThirteenLinearLayout.setTag(detailId);
				mTypeThirteenView.setTag(mType);
				linearLayout.addView(mTypeThirteenView);
				
				new AsyncTask<Void, Void, Void>() {
					@Override
					protected Void doInBackground(Void... params) {
						if (mIntentFrom == FLAG_SHOW || mIntentFrom == FLAG_UPDATE) {// 查看,修改
							mFormDetailMap = GdjtUserDataDBOperation.getInstance().getChildListDetailValueData(mUTableID, detailId);
						} else {// 添加
							mFormZuDetailChildList = GdjtFormDBOperation.getInstance().getChildListDetailData(detailId);
						}
						return null;
					}

					@Override
					protected void onPostExecute(Void result) {
						
						if (mIntentFrom == FLAG_SHOW || mIntentFrom == FLAG_UPDATE ) {
							ShowChildView();
						} else {
							AddZuChildView();
						}
						// linearLayout.refreshDrawableState();
					}
				}.execute();

			} else if (mType == ViewTypeUtil.item_view_type_fourteen) {// 日期时间格式
				mTypeFourteenView = LayoutInflater.from(this).inflate(R.layout.item_type_three, null);
				mFourteenDateKeyTv = (TextView) mTypeFourteenView.findViewById(R.id.tv_test_date_key);
				mFourteenDateValueEt = (EditText) mTypeFourteenView.findViewById(R.id.et_test_date_value);
				mFourteenDateValueEt.setTag(formDetail.getTableDetailID());
				mFourteenDateKeyTv.setText(formDetail.getCaption());
				if (mIntentFrom == FLAG_SHOW) {
					mFourteenDateValueEt.setEnabled(false);
				}
				if (!TextUtils.isEmpty(formDetail.getuValue())) {
					mFourteenDateValueEt.setText(formDetail.getuValue());
				} else {
					mFourteenDateValueEt.setText(TimeUtil.getCurDateStr());
				}
				mFourteenDateValueEt.setTag(formDetail.getTableDetailID());
				mFourteenDateValueEt.setOnClickListener(this);
				mTypeFourteenView.setTag(mType);
				linearLayout.addView(mTypeFourteenView);
			} else if (mType == ViewTypeUtil.item_view_type_fifteen) {// 时间格式
				mTypeFifteenView = LayoutInflater.from(this).inflate(R.layout.item_type_three, null);
				mFifteenDateKeyTv = (TextView) mTypeFifteenView.findViewById(R.id.tv_test_date_key);
				mFifteenDateValueEt = (EditText) mTypeFifteenView.findViewById(R.id.et_test_date_value);
				mFifteenDateValueEt.setTag(formDetail.getTableDetailID());
				mFifteenDateKeyTv.setText(formDetail.getCaption());
				if (mIntentFrom == FLAG_SHOW) {
					mFifteenDateValueEt.setEnabled(false);
				}
				if (!TextUtils.isEmpty(formDetail.getuValue())) {
					mFifteenDateValueEt.setText(formDetail.getuValue());
				} else {
					mFifteenDateValueEt.setText(TimeUtil.getStringTimeShort());
				}
				mFifteenDateValueEt.setTag(formDetail.getTableDetailID());
				mFifteenDateValueEt.setOnClickListener(this);
				mTypeFifteenView.setTag(mType);
				linearLayout.addView(mTypeFifteenView);
			} else if (mType == ViewTypeUtil.item_view_type_sixteen) {// 标签
				mTypeSixteenView = LayoutInflater.from(this).inflate(R.layout.item_type_zero, null);
				mItemSixteenFieldTv = (TextView) mTypeSixteenView.findViewById(R.id.item_zero_field_tv);
				mItemSixteenValueEt = (EditText) mTypeSixteenView.findViewById(R.id.item_zero_value_et);
				mItemSixteenValueEt.setEnabled(false);
				mItemSixteenValueEt.setText(formDetail.getuValue());
				mItemSixteenValueEt.setTag(formDetail.getTableDetailID());
				mItemSixteenFieldTv.setText(formDetail.getCaption());
				mTypeSixteenView.setTag(mType);
				linearLayout.addView(mTypeSixteenView);
			}
		}
	}

 

 

3.处理复杂控件 

其实这个里面的复杂控件就两种,一种是列表 一种是组

给简单大家解释一下列表是什么意思:  大家看有的表格里面是多行多列的,意味着同样的字段数据 可能要添写多条。

那么对应在app里面   就是 这些字段放到了一起  做成了一个 组。  那么这些字段添加多条 就是 在组后面放了一个 + 号

点击+号  这个组 就增加一组 。所以这个带+号的字段 就是 列表字段。

 

组和 列表 处理起来相对来说非常麻烦。

 

1).子项数据获取   

2).布局嵌套

3).点击事件单独处理

4)保存数据独立拼接

 

具体这些问题,我就不一一展开说了。大家倘若有做的,具体做的时候自然会体会到。    

 

4.处理点击事件

界面拼接完成后 ,要处理控件里面的点击事件。做的时候就会发现  倘若界面出现同一个item布局  ,布局里面包含点击事件 ,正常给控件设置点击事件,会发现 点击控件的时候无法区分开每个点击事件

所以处理点击事件的时候:原理  就是先循环整体的大布局 ,找到里面的每一项小布局,然后单独处理每一项小布局里面的控件。

这样才能保证点击事件没有问题。

代码贴一下:

 

@Override
	public void onClick(View v) {
		 if (v.getId() == R.id.content_iv) {// 范例

		} else if (v.getId() == R.id.voice_iv) {// 语音
			for (int i = 0; i < mMainView.getChildCount(); i++) {
				int viewTag = (int) mMainView.getChildAt(i).getTag();
				if (viewTag == ViewTypeUtil.item_view_type_two) {
					LinearLayout l = (LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0);
					EditText editText = (EditText) l.getChildAt(1);
					if (v.getTag().equals(editText.getTag())) {
						mVoice = new VoiceToWord(this, editText);
						mVoice.GetWordFromVoice();
					}
				} else if (viewTag == ViewTypeUtil.item_view_type_thirteen || viewTag == ViewTypeUtil.item_view_type_ten) {
					LinearLayout l = (LinearLayout) ((LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0)).getChildAt(1);
					for (int j = 0; j < l.getChildCount(); j++) {
						LinearLayout l_add = (LinearLayout) ((LinearLayout) l.getChildAt(j));
						for (int k = 0; k < l_add.getChildCount(); k++) {
							int viewTag_child = (int) l_add.getChildAt(k).getTag();
							if (viewTag_child == ViewTypeUtil.item_view_type_two) {
								LinearLayout l_view = (LinearLayout) ((LinearLayout) l_add.getChildAt(k)).getChildAt(0);
								EditText editText = (EditText) l_view.getChildAt(1);
								if (v.getTag().equals(editText.getTag())) {
									mVoice = new VoiceToWord(this, editText);
									mVoice.GetWordFromVoice();
								}
							}
						}
					}
				}
			}
		} else if (v.getId() == R.id.special_iv) {// 特殊字符
			for (int i = 0; i < mMainView.getChildCount(); i++) {
				int viewTag = (int) mMainView.getChildAt(i).getTag();
				if (viewTag == ViewTypeUtil.item_view_type_two) {
					LinearLayout l = (LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0);
					EditText editText = (EditText) l.getChildAt(1);
					if (v.getTag().equals(editText.getTag())) {
						mSpecialdialog = new SpecialWordsDialog(context, editText);
					}
				} else if (viewTag == ViewTypeUtil.item_view_type_thirteen || viewTag == ViewTypeUtil.item_view_type_ten) {
					LinearLayout l = (LinearLayout) ((LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0)).getChildAt(1);
					for (int j = 0; j < l.getChildCount(); j++) {
						LinearLayout l_add = (LinearLayout) ((LinearLayout) l.getChildAt(j));
						for (int k = 0; k < l_add.getChildCount(); k++) {
							int viewTag_child = (int) l_add.getChildAt(k).getTag();
							if (viewTag_child == ViewTypeUtil.item_view_type_two) {
								LinearLayout l_view = (LinearLayout) ((LinearLayout) l_add.getChildAt(k)).getChildAt(0);
								EditText editText = (EditText) l_view.getChildAt(1);
								if (v.getTag().equals(editText.getTag())) {
									mSpecialdialog = new SpecialWordsDialog(context, editText);
								}
							}
						}
					}
				}
			}
		} else if (v.getId() == R.id.et_test_date_value) {// 时间选择

			for (int i = 0; i < mMainView.getChildCount(); i++) {
				int viewTag = (int) mMainView.getChildAt(i).getTag();
				if (viewTag == ViewTypeUtil.item_view_type_three) {
					LinearLayout l = (LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0);
					EditText editText = (EditText) l.getChildAt(1);
					if (v.getTag().equals(editText.getTag())) {
						DlgUtil.showDateTimePickerDlgByType(this, editText, 1);
					}
				} else if (viewTag == ViewTypeUtil.item_view_type_fourteen) {
					LinearLayout l = (LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0);
					EditText editText = (EditText) l.getChildAt(1);
					if (v.getTag().equals(editText.getTag())) {
						DlgUtil.showDateTimePickerDlg(this, editText);

					}
				} else if (viewTag == ViewTypeUtil.item_view_type_fifteen) {
					LinearLayout l = (LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0);
					EditText editText = (EditText) l.getChildAt(1);
					if (v.getTag().equals(editText.getTag())) {
						DlgUtil.showDateTimePickerDlgByType(this, editText, 2);
					}
				} else if (viewTag == ViewTypeUtil.item_view_type_thirteen || viewTag == ViewTypeUtil.item_view_type_ten) {
					LinearLayout l = (LinearLayout) ((LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0)).getChildAt(1);
					for (int j = 0; j < l.getChildCount(); j++) {
						LinearLayout l_add = (LinearLayout) ((LinearLayout) l.getChildAt(j));
						for (int k = 0; k < l_add.getChildCount(); k++) {
							int viewTag_child = (int) l_add.getChildAt(k).getTag();
							if (viewTag_child == ViewTypeUtil.item_view_type_three) {
								LinearLayout l_view = (LinearLayout) ((LinearLayout) l_add.getChildAt(i)).getChildAt(0);
								EditText editText = (EditText) l_view.getChildAt(1);
								if (v.getTag().equals(editText.getTag())) {
									DlgUtil.showDateTimePickerDlgByType(this, editText, 1);
								}
							} else if (viewTag_child == ViewTypeUtil.item_view_type_fourteen) {
								LinearLayout l_view = (LinearLayout) ((LinearLayout) l_add.getChildAt(i)).getChildAt(0);
								EditText editText = (EditText) l_view.getChildAt(1);
								if (v.getTag().equals(editText.getTag())) {
									DlgUtil.showDateTimePickerDlg(this, editText);

								}
							} else if (viewTag_child == ViewTypeUtil.item_view_type_fifteen) {
								LinearLayout l_view = (LinearLayout) ((LinearLayout) l_add.getChildAt(i)).getChildAt(0);
								EditText editText = (EditText) l_view.getChildAt(1);
								if (v.getTag().equals(editText.getTag())) {
									DlgUtil.showDateTimePickerDlgByType(this, editText, 2);
								}
							}
						}
					}
				}
			}

		} else if (v.getId() == R.id.et_select_value) {
			for (int i = 0; i < mMainView.getChildCount(); i++) {
				int viewTag = (int) mMainView.getChildAt(i).getTag();
				if (viewTag == ViewTypeUtil.item_view_type_five) {
					LinearLayout l = (LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0);
					final EditText editText = (EditText) l.getChildAt(1);
					if (v.getTag(R.id.select_view_detial_id).equals(editText.getTag(R.id.select_view_detial_id))) {
						int position = (int) editText.getTag(R.id.select_view_position);
						mDataList.clear();
						List<DicBean> dicList = mFormDetailList.get(position).dicBeanList;
						for (DicBean dicBean : dicList) {
							mDataList.add(dicBean.getDicName());
						}
						CusSpinerAdapter<String> mAdapter = new CusSpinerAdapter<String>(this);
						mAdapter.refreshData(mDataList, 0);
						View contentView = LayoutInflater.from(context).inflate(R.layout.common_form_view, null);
						SpinerPopWindow mSpinerPopWindow = new SpinerPopWindow(this, R.layout.spiner_window_layout, true);
						mSpinerPopWindow.setAdatper(mAdapter);
						mSpinerPopWindow.setItemListener(new IOnItemSelectListener() {

							@Override
							public void onItemClick(int pos) {
								if (pos >= 0 && pos <= mDataList.size()) {
									String value = (String) mDataList.get(pos);
									editText.setText(value.toString());
								}
							}
						});
						mSpinerPopWindow.setWidth(editText.getWidth());

						int windowPos[] = PopMeasure.calculatePopWindowPos(editText, contentView);
						int xOff = 25;// 可以自己调整偏移
						windowPos[0] -= xOff;
						mSpinerPopWindow.showAtLocation(v, Gravity.TOP | Gravity.START, windowPos[0], windowPos[1]);
					}
				}else if(viewTag == ViewTypeUtil.item_view_type_thirteen || viewTag == ViewTypeUtil.item_view_type_ten){
					LinearLayout l = (LinearLayout) ((LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0)).getChildAt(1);
					for (int j = 0; j < l.getChildCount(); j++) {
						LinearLayout l_add = (LinearLayout) ((LinearLayout) l.getChildAt(j));//第二层布局layout
						for (int k = 0; k < l_add.getChildCount(); k++) {
							int viewTag_child = (int) l_add.getChildAt(k).getTag();
							if(viewTag_child == ViewTypeUtil.item_view_type_five){
								LinearLayout l_view = (LinearLayout) ((LinearLayout) l_add.getChildAt(k)).getChildAt(0);//第三层每一项
								final EditText editText = (EditText) l_view.getChildAt(1);
								if (v.getTag(R.id.select_view_detial_id).equals(editText.getTag(R.id.select_view_detial_id))) {
									int position = (int) editText.getTag(R.id.select_view_position);
									mDataList.clear();
									List<DicBean> dicList = new ArrayList<FormDetailBean.FormDetail.DicBean>();
									if (viewTag == ViewTypeUtil.item_view_type_ten) {
										dicList = mFormDetailChildList.get(position).dicBeanList;
									}else if (viewTag == ViewTypeUtil.item_view_type_thirteen) {
										dicList = mFormZuDetailChildList.get(position).dicBeanList;
									}
									
									for (DicBean dicBean : dicList) {
										mDataList.add(dicBean.getDicName());
									}
									CusSpinerAdapter<String> mAdapter = new CusSpinerAdapter<String>(this);
									mAdapter.refreshData(mDataList, 0);
									View contentView = LayoutInflater.from(context).inflate(R.layout.common_form_view, null);
									SpinerPopWindow mSpinerPopWindow = new SpinerPopWindow(this, R.layout.spiner_window_layout, true);
									mSpinerPopWindow.setAdatper(mAdapter);
									mSpinerPopWindow.setItemListener(new IOnItemSelectListener() {

										@Override
										public void onItemClick(int pos) {
											if (pos >= 0 && pos <= mDataList.size()) {
												String value = (String) mDataList.get(pos);
												editText.setText(value.toString());
											}
										}
									});
									mSpinerPopWindow.setWidth(editText.getWidth());
									
									int windowPos[] = PopMeasure.calculatePopWindowPos(editText, contentView);
									int xOff = 200;// 可以自己调整偏移
									windowPos[0] -= xOff;
									mSpinerPopWindow.showAtLocation(v, Gravity.TOP | Gravity.START,windowPos[0], windowPos[1]);
								}
							}else if(viewTag_child == ViewTypeUtil.item_view_type_thirteen || viewTag_child == ViewTypeUtil.item_view_type_ten){
								LinearLayout l3 =  (LinearLayout) ((LinearLayout) ((LinearLayout) l_add.getChildAt(k)).getChildAt(0)).getChildAt(1);
								for (int j3 = 0; j3 < l3.getChildCount(); j3++) {
									LinearLayout l_add3 = (LinearLayout) ((LinearLayout) l3.getChildAt(j3));
									for (int k3 = 0; k3 < l_add3.getChildCount(); k3++) {
										int viewTag_child3 = (int) l_add3.getChildAt(k3).getTag();
										if(viewTag_child3 == ViewTypeUtil.item_view_type_five){
											LinearLayout l_view = (LinearLayout) ((LinearLayout) l_add3.getChildAt(k3)).getChildAt(0);
											final EditText editText = (EditText) l_view.getChildAt(1);
											if (v.getTag(R.id.select_view_detial_id).equals(editText.getTag(R.id.select_view_detial_id))) {
												int position = (int) editText.getTag(R.id.select_view_position);
												mDataList.clear();
												List<DicBean> dicList = mFormZuDetailChildList.get(position).dicBeanList;
												for (DicBean dicBean : dicList) {
													mDataList.add(dicBean.getDicName());
												}
												CusSpinerAdapter<String> mAdapter = new CusSpinerAdapter<String>(this);
												mAdapter.refreshData(mDataList, 0);
												View contentView = LayoutInflater.from(context).inflate(R.layout.common_form_view, null);
												SpinerPopWindow mSpinerPopWindow = new SpinerPopWindow(this, R.layout.spiner_window_layout, true);
												mSpinerPopWindow.setAdatper(mAdapter);
												mSpinerPopWindow.setItemListener(new IOnItemSelectListener() {

													@Override
													public void onItemClick(int pos) {
														if (pos >= 0 && pos <= mDataList.size()) {
															String value = (String) mDataList.get(pos);
															editText.setText(value.toString());
														}
													}
												});
												mSpinerPopWindow.setWidth(editText.getWidth());
												
												int windowPos[] = PopMeasure.calculatePopWindowPos(editText, contentView);
												int xOff = 200;// 可以自己调整偏移
												windowPos[0] -= xOff;
												mSpinerPopWindow.showAtLocation(v, Gravity.TOP | Gravity.START,windowPos[0], windowPos[1]);
											}
										}
									}
								}
							}
						}
					}
				}
			}
		} else if (v.getId() == R.id.et_select_part_value) {
			CheckPart_Monomer_Activity.actionStartForResult(context, mPartSelectValueEt.getText().toString(), "", "", monomerId, CheckPart_Monomer_Activity.class);
		} else if (v.getId() == R.id.cbx_type_nine) {// 类型9 多选框意向
			for (int i = 0; i < mMainView.getChildCount(); i++) {
				int viewTag = (int) mMainView.getChildAt(i).getTag();
				if (viewTag == ViewTypeUtil.item_view_type_nine) {
					LinearLayout l = (LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0);
					CheckBox checkBox = (CheckBox) l.getChildAt(1);
				} else if (viewTag == ViewTypeUtil.item_view_type_thirteen || viewTag == ViewTypeUtil.item_view_type_ten) {
					LinearLayout l = (LinearLayout) ((LinearLayout) ((LinearLayout) mMainView.getChildAt(i)).getChildAt(0)).getChildAt(1);
					for (int j = 0; j < l.getChildCount(); j++) {
						LinearLayout l_add = (LinearLayout) ((LinearLayout) l.getChildAt(j));
						for (int k = 0; k < l_add.getChildCount(); k++) {
							int viewTag_child = (int) l_add.getChildAt(k).getTag();
							if (viewTag_child == ViewTypeUtil.item_view_type_nine) {
								LinearLayout l_view = (LinearLayout) ((LinearLayout) l_add.getChildAt(k)).getChildAt(0);
								CheckBox checkBox = (CheckBox) l_view.getChildAt(1);
							}
						}
					}
				}
			}

		} else if (v.getId() == R.id.item_eleven_value_et) {
			for (int i = 0; i < mMainView.getChildCount(); i++) {
				int viewTag = (int) mMainView.getChildAt(i).getTag(); 
				if (viewTag == ViewTypeUtil.item_view_type_eleven) {
					if (!TextUtils.isEmpty(mDrawingPath)) {
						Intent intent = new Intent(CommonFormViewActivity.this, DrawingTypeActivity.class);
						intent.putExtra("drawingPath", mDrawingPath);
						intent.putExtra("tableDetailID", (String) v.getTag());
						intent.putExtra("intent_from", FLAG_UPDATE);
						if (mIntentFrom == FLAG_SHOW || mIntentFrom == FLAG_UPDATE) {// 查看,修改记录
							intent.putExtra("RecordId", mUTableID);
						}
						startActivityForResult(intent, 11);
					}
				}
			}

		} else if (v.getId() == R.id.item_eleven_value_img_photo) {// 类型11图纸标准类型拍照按钮
			mViewTypeFlag = ViewTypeUtil.item_view_type_eleven;
			if (mCreateBmpFactory == null) {
				mCreateBmpFactory = new CreateBmpFactory(CommonFormViewActivity.this);
			}
			mCreateBmpFactory.OpenCamera();
		} else if (v.getId() == R.id.item_eleven_value_img_folder) {// 类型11图纸标准类型从图库选择
			mViewTypeFlag = ViewTypeUtil.item_view_type_eleven;
			FileSelect chosen = new FileSelect(CommonFormViewActivity.this);
			chosen.setOnFileSelecteListener(new OnFileSelecteListener() {
				@Override
				public void onFileSelected(String filePath, String fileName) {
					mDrawingPath = filePath;
					mDrawingNameTv.setText(fileName);
					Intent intent1 = new Intent(CommonFormViewActivity.this, DrawingTypeActivity.class);
					intent1.putExtra("drawingPath", mDrawingPath);
					intent1.putExtra("tableDetailID", (String) mDrawingNameTv.getTag());
					intent1.putExtra("intent_from", FLAG_UPDATE);
					if (mIntentFrom == FLAG_SHOW || mIntentFrom == FLAG_UPDATE) {// 查看,修改记录
						intent1.putExtra("RecordId", mUTableID);
					}
					startActivityForResult(intent1, 11);
				}
			});
			chosen.showChosenDialog();

		} else if (v.getId() == R.id.item_twelve_value_path) {// 类型12 图片路径
			
		} else if (v.getId() == R.id.item_twelve_value_img_photo) {// 类型12拍照
			mViewTypeFlag = ViewTypeUtil.item_view_type_twelve;
			mViewTag = v.getTag();
			if (mCreateBmpFactory == null) {
				mCreateBmpFactory = new CreateBmpFactory(CommonFormViewActivity.this);
			}
			mCreateBmpFactory.OpenCamera();
		} else if (v.getId() == R.id.item_twelve_value_img_folder) {// 类型12
			mViewTypeFlag = ViewTypeUtil.item_view_type_twelve;
			mViewTag = v.getTag();
			if (mCreateBmpFactory == null) {
				mCreateBmpFactory = new CreateBmpFactory(CommonFormViewActivity.this);
			}
			mCreateBmpFactory.OpenGallery();

		} else if (v.getId() == R.id.iv_type_ten_add) {
			AddListChildView();
		}
	}


估计这么写看看都会头晕,因为这上面代码 里面除了处理正常的点击事件,还要处理列表和组  也就是 嵌套布局里面的点击事件。但是原理都是一样的。

 

就是循环布局找到 你点击的那个布局,那个控件...  如果是嵌套多级  就一级一级的找...

5.保存上传数据

我们这边保存处理的逻辑就是将界面上所有的数据都拼成一个JSONOject  里面套JSONArray和JSONObject ,反正就是根据自己的业务往里面套数据,这个数据组织起来稍微有一点点麻烦。

代码贴一下:

 

package com.jky.xmxtcommonlib.utils;

import org.json.JSONException;
import org.json.JSONObject;

import com.jky.xmxtcommonlib.R;

import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;

/**
 * Created by zlw on 2017/6/13.
 */
public class GetViewValueUtil {

	// 表格输入框取值方法
	public static JSONObject getTypeZeroValue(LinearLayout linearLayout, JSONObject jsonObject) throws JSONException {
		EditText editText = (EditText) linearLayout.getChildAt(1);
		String id = editText.getTag() + "";
		String str = editText.getText().toString().trim();
		jsonObject.put(id + "", str);
		return jsonObject;
	}

	
	// 单行输入框取值方法
	public static JSONObject getTypeOneValue(LinearLayout linearLayout, JSONObject jsonObject) throws JSONException {
		EditText editText = (EditText) linearLayout.getChildAt(1);
		String id = editText.getTag() + "";
		String str = editText.getText().toString().trim();
		jsonObject.put(id + "", str);
		return jsonObject;
	}

	// 多行输入框取值方法
	public static JSONObject getTypeTwoValue(LinearLayout linearLayout, JSONObject jsonObject) throws JSONException {
		EditText editText = (EditText) linearLayout.getChildAt(1);
		String id = editText.getTag() + "";
		String str = editText.getText().toString().trim();
		jsonObject.put(id + "", str);
		return jsonObject;
	}

	// 时间选择框取值方法
	public static JSONObject getTypeThreeValue(LinearLayout linearLayout, JSONObject jsonObject) throws JSONException {
		if(linearLayout !=null){
			EditText editText = (EditText) linearLayout.getChildAt(1);
			if(editText!=null){
				String id = editText.getTag() + "";
				String str = editText.getText().toString().trim();
				jsonObject.put(id + "", str);
			}else{
				JSONObject json= new JSONObject();
				return json;
			}
		} else {
			JSONObject json= new JSONObject();
			return json;
		}
		
		return jsonObject;
	}

	// 数值输入框取值方法
	public static JSONObject getTypeFourValue(LinearLayout linearLayout, JSONObject jsonObject) throws JSONException {
		EditText editText = (EditText) linearLayout.getChildAt(1);
		String id = editText.getTag() + "";
		String str = editText.getText().toString().trim();
		jsonObject.put(id + "", str);
		return jsonObject;
	}

	// 下拉选择框取值方法
	public static JSONObject getTypeFiveValue(LinearLayout linearLayout, JSONObject jsonObject) throws JSONException {
		EditText editText = (EditText) linearLayout.getChildAt(1);
		String id = editText.getTag(R.id.select_view_detial_id) + "";
		String str = editText.getText().toString().trim();
		jsonObject.put(id + "", str);
		return jsonObject;
	}

	// 部位选择框取值方法
	public static JSONObject getTypeSevenValue(LinearLayout linearLayout, JSONObject jsonObject) throws JSONException {
		EditText editText = (EditText) linearLayout.getChildAt(1);
		String id = editText.getTag() + "";
		String str = editText.getText().toString().trim();
		jsonObject.put(id + "", str);
		return jsonObject;
	}

	// 单选框取值方法
	public static JSONObject getTypeEightValue(LinearLayout linearLayout, JSONObject jsonObject) throws JSONException {
		RadioGroup radioGroup = (RadioGroup) linearLayout.getChildAt(1);
		for (int i = 0; i < radioGroup.getChildCount(); i++) {
			RadioButton radioButton = (RadioButton) radioGroup.getChildAt(i);
			String  str = (String) radioButton.getTag();
			String detailId = str.split(",")[0];
			String dicId = str.split(",")[1];
			if (radioButton.isChecked()) {
					jsonObject.put(detailId + "", dicId);
			}
		}
		return jsonObject;
	}

	// 多选框取值方法
	public static JSONObject getTypeNineValue(LinearLayout linearLayout, JSONObject jsonObject) throws JSONException {
		CheckBox checkBox = (CheckBox) linearLayout.getChildAt(1);
		String value = "";
		String  str = (String) checkBox.getTag();
		if (checkBox.isChecked()) {
			value = checkBox.getText().toString().trim();
			String detailId = str.split(",")[0];
			String dicId = str.split(",")[1];
			jsonObject.put(detailId,dicId);
		} else {
			String detailId = str.split(",")[0];
			jsonObject.put(detailId, "0");
		}
		
		return jsonObject;
	}
	
	// 图纸类表格类型存值
		public static JSONObject getTypeElevenValue(LinearLayout linearLayout,String path, JSONObject jsonObject) throws JSONException {
			TextView extView = (TextView) linearLayout.getChildAt(1);
			String id = extView.getTag() + "";
			String str = path.trim();
			jsonObject.put(id + "", str);
			return jsonObject;
		}
	// 照片类表格类型存值
	public static JSONObject getTypeTwelveValue(LinearLayout linearLayout,String path, JSONObject jsonObject) throws JSONException {
		TextView extView = (TextView) linearLayout.getChildAt(0);
		String id = extView.getTag() + "";
		String str = path.trim();
		jsonObject.put(id + "", str);
		return jsonObject;
	}
}
	/**
	 * 得到需要保存的json数据
	 * 
	 * @param linearLayout
	 * @param isChildFlag
	 * @param jsonKey
	 * @throws JSONException
	 */
	private void getJsonInfo(LinearLayout linearLayout) throws JSONException {
		for (int i = 0; i < linearLayout.getChildCount(); i++) {
			int viewTag = (int) linearLayout.getChildAt(i).getTag();
			if (viewTag == ViewTypeUtil.item_view_type_zero) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				mJsonObject = GetViewValueUtil.getTypeZeroValue(l, mJsonObject);
			} else if (viewTag == ViewTypeUtil.item_view_type_one) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				mJsonObject = GetViewValueUtil.getTypeOneValue(l, mJsonObject);
			} else if (viewTag == ViewTypeUtil.item_view_type_two) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				mJsonObject = GetViewValueUtil.getTypeTwoValue(l, mJsonObject);
			} else if (viewTag == ViewTypeUtil.item_view_type_three) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				mJsonObject = GetViewValueUtil.getTypeThreeValue(l, mJsonObject);
			} else if (viewTag == ViewTypeUtil.item_view_type_four) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				mJsonObject = GetViewValueUtil.getTypeFourValue(l, mJsonObject);

			} else if (viewTag == ViewTypeUtil.item_view_type_five) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				mJsonObject = GetViewValueUtil.getTypeFiveValue(l, mJsonObject);
			} else if (viewTag == ViewTypeUtil.item_view_type_six) {

			} else if (viewTag == ViewTypeUtil.item_view_type_seven) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				mJsonObject = GetViewValueUtil.getTypeSevenValue(l, mJsonObject);
			} else if (viewTag == ViewTypeUtil.item_view_type_eight) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				mJsonObject = GetViewValueUtil.getTypeEightValue(l, mJsonObject);
			} else if (viewTag == ViewTypeUtil.item_view_type_nine) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				mJsonObject = GetViewValueUtil.getTypeNineValue(l, mJsonObject);
			} else if (viewTag == ViewTypeUtil.item_view_type_ten) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				LinearLayout layout = (LinearLayout) l.getChildAt(1);
				getSecondJsonInfo(layout, (String) layout.getTag());
				mJsonObject.put((String) layout.getTag(), mSecondJsonArray);
			} else if (viewTag == ViewTypeUtil.item_view_type_eleven) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				if (!TextUtils.isEmpty(mDrawingPath)) {
					mJsonObject = GetViewValueUtil.getTypeElevenValue(l, mDrawingPath, mJsonObject);
				}
			} else if (viewTag == ViewTypeUtil.item_view_type_twelve) {
				if(!TextUtils.isEmpty(mPhotoPath)){
					LinearLayout l = (LinearLayout) ((LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0)).getChildAt(1);
					mJsonObject = GetViewValueUtil.getTypeTwelveValue(l, mPhotoPath, mJsonObject);
				}
			} else if (viewTag == ViewTypeUtil.item_view_type_thirteen) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				LinearLayout layout = (LinearLayout) l.getChildAt(1);
				getSecondJsonInfo(layout, (String) layout.getTag());
				mJsonObject.put((String) layout.getTag(), mSecondJsonArray);
			} else if (viewTag == ViewTypeUtil.item_view_type_fourteen) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				mJsonObject = GetViewValueUtil.getTypeThreeValue(l, mJsonObject);
			} else if (viewTag == ViewTypeUtil.item_view_type_fifteen) {
				LinearLayout l = (LinearLayout) ((LinearLayout) linearLayout.getChildAt(i)).getChildAt(0);
				mJsonObject = GetViewValueUtil.getTypeThreeValue(l, mJsonObject);
			}
		}
	}

 


大概意思就是这样,核心的就是这个,其实也不是很复杂。

 

 

 

这样就实现了动态拼接app界面,不用重复性的写大量的界面,当然一般app是没有这么恶心的功能的...但我还是贴出来,希望能帮到后面入坑的同学....

 

这个由于直接在项目里面写的,不容易抽剥代码。demo暂时先不整理了,大家如果有问题可以加入我的qq群讨论
 

开发一群:454430053开发二群:537532956

 

2018-02-26 23:38:32 xy1213236113 阅读数 1925

第一种情况:不同压缩格式音频拼接,不同的压缩格式拼接需要解码为采样数据然后拼接,然后再编码为统一的压缩格式。
这里写图片描述

方法一:FFmpeg命令拼接,ffmpeg -I ‘concat:0.mp3|1.wav|2.aac’ -acodec copy merge.mp3。(注意:这种方式,速度相对还可以,但是在android设备上一下子拼接6个音频以上就会奔溃,应该是C代码中有什么变量没有释放掉)

  static {
        System.loadLibrary("MyLib");
    }
  public native void command(int len,String[] argv);
 /**
     * 使用ffmpeg命令行进行音频合并
     * @param src 源文件
     * @param targetFile 目标文件
     * @return 合并后的文件
     */
    public static  String[] concatAudio(String[] src, String targetFile){
        String join = StringUtils.join("|", src);
        String concatAudioCmd = "ffmpeg -i concat:%s -acodec copy %s";//%s|%s
        concatAudioCmd = String.format(concatAudioCmd, join, targetFile);
        return concatAudioCmd.split(" ");//以空格分割为字符串数组
    }

   /**
     * 拼接音频
     * @param paths 音频地址集合
     * @return 音频拼接之后的地址
     */
    private String jointAudio1(List<String> paths) {
        String path = "";
        for (int i = 1; i < paths.size(); i++) {
            String[] pathArr = new String[2];
                if (i==1) {
                    pathArr[0] = paths.get(i - 1);
                    pathArr[1] = paths.get(i);
                }else{
                    pathArr[0] = path;
                    pathArr[1] = paths.get(i);
                }
            File file = new File(paths.get(0));
            path = file.getParent().concat(File.separator).concat(String.valueOf(System.currentTimeMillis()).concat("-debris.mp3"));
            String[] command = FFmpegUtil.concatAudio(pathArr, path);
            command(command.length,command);
        }
        return path;
    }
#include <jni.h>
#include <malloc.h>
#include <string.h>
#include "ffmpeg.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
//音频采样
#include <libswresample/swresample.h>
#include <android/log.h>
#define LOG_I_ARGS(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"main",FORMAT,__VA_ARGS__);
#define LOG_I(FORMAT) LOG_I_ARGS(FORMAT,0);

//视频转码压缩主函数入口
//ffmpeg_mod.c有一个FFmpeg视频转码主函数入口
// argc = str.split(" ").length()
// argv = str.split(" ")  字符串数组
//参数一:命令行字符串命令个数
//参数二:命令行字符串数组
int ffmpegmain(int argc, char **argv);


JNIEXPORT void JNICALL Java_com_xy_openndk_audiojointdemo_FFmpegLib_command
        (JNIEnv *env, jobject jobj,jint jlen,jobjectArray jobjArray){
    //转码
    //将java的字符串数组转成C字符串
    int argc = jlen;
    //开辟内存空间
    char **argv = (char**)malloc(sizeof(char*) * argc);

    //填充内容
    for (int i = 0; i < argc; ++i) {
        jstring str = (*env)->GetObjectArrayElement(env,jobjArray,i);
        const char* tem = (*env)->GetStringUTFChars(env,str,0);
        argv[i] = (char*)malloc(sizeof(char)*1024);
        strcpy(argv[i],tem);
        (*env)->ReleaseStringUTFChars(env,str,tem);
    }
    //开始转码(底层实现就是只需命令)
    ffmpegmain(argc,argv);
    //释放内存空间
    for (int i = 0; i < argc; ++i) {
        free(argv[i]);
    }
    //释放数组
    free(argv);
}

方法二:FFmpeg解码为采样数据之后拼接采样数据,然后再编码为压缩格式数据。这里我选用了FFmpeg进行编解码,当然也可以选择Android系统提供的MediaCodec进行解码拼接再编码。(注意:这种方式速度很慢很慢的,但这种方式是最安全科学的做法。)

include <jni.h>
#include <android/log.h>
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/imgutils.h"
#include "libswscale/swscale.h"
//音频采样
#include "libswresample/swresample.h"
#include "mp3enc/lame.h"
}
#define LOG_I_ARGS(FORMAT, ...) __android_log_print(ANDROID_LOG_INFO,"main",FORMAT,__VA_ARGS__);
#define LOG_I(FORMAT) LOG_I_ARGS(FORMAT,0);
#define MAX_AUDIO_FRAME_SIZE (44100)
AVFormatContext *av_fm_ctx = NULL;
AVCodecParameters *av_codec_pm = NULL;
AVCodec *av_codec = NULL;
AVCodecContext *av_codec_ctx = NULL;
AVPacket *packet = NULL;
AVFrame *in_frame = NULL;
SwrContext *swr_ctx = NULL;
uint8_t *out_buffer = NULL;

/**
 * 音频解码
 * @param out 拼接的采样数据文件
 * @param path 音频地址
 */
void decodeAudio(FILE *out, const char *path);

/**
 * 音频编码
 * @param path PCM文件地址
 * @param out 输出文件地址
 */
void encoder(const char* path,const char* out);

extern "C"
JNIEXPORT void JNICALL
Java_com_xy_audio_ffmpegjointaudio_MainActivity_jointAudio(JNIEnv *env, jobject instance,
                                                           jobjectArray paths_, jstring path_,jstring other_) {
    jsize len = env->GetArrayLength(paths_);
    //音频输入文件
    const char *out = env->GetStringUTFChars(path_, NULL);
    const char* other = env->GetStringUTFChars(other_,NULL);
//    //写入文件
    FILE *file_out_dcm = fopen(out, "wb+");
    //注册输入输出组件
    av_register_all();

    for (int i = 0; i < len; i++) {
        jstring str = (jstring) env->GetObjectArrayElement(paths_, i);
        const char *path = env->GetStringUTFChars(str, 0);
        LOG_I(path);
        //解码拼接
        decodeAudio(file_out_dcm, path);
        env->ReleaseStringUTFChars(str, path);
    }
    fclose(file_out_dcm);
    env->ReleaseStringUTFChars(path_, out);
    env->ReleaseStringUTFChars(other_,other);
    av_packet_free(&packet);
    if(out_buffer != NULL)
    av_freep(out_buffer);
    avformat_close_input(&av_fm_ctx);
    avformat_free_context(av_fm_ctx);
    //编码
    encoder(out,other);
}

/**
 * 音频解码
 * @param out 输出文件
 * @param path 解码的文件地址
 */
void decodeAudio(FILE *out, const char *path) {
    av_fm_ctx = avformat_alloc_context();
    int av_fm_open_result = avformat_open_input(&av_fm_ctx, path, NULL, NULL);
    if (av_fm_open_result != 0) {
        LOG_I("打开失败!");
        return;
    }
    //获取音频文件信息
    if (avformat_find_stream_info(av_fm_ctx, NULL) < 0) {
        LOG_I("获取信息失败");
        return;
    }
    //查找音频解码器
    //找到音频流索引位置
    int audio_stream_index = -1;
    for (int i = 0; i < av_fm_ctx->nb_streams; i++) {
        //查找音频流索引位置
        if (av_fm_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
            audio_stream_index = i;
            break;
        }
    }
    //判断是否存在音频流
    if (audio_stream_index == -1) {
        LOG_I("没有这个音频流!");
        return;
    }
    //获取编码器上下文(获取编码器ID)
    av_codec_pm = av_fm_ctx->streams[audio_stream_index]->codecpar;

    //获取解码器(根据编码器的ID,找到对应的解码器)
    av_codec = avcodec_find_decoder(av_codec_pm->codec_id);
    //打开解码器
    av_codec_ctx = avcodec_alloc_context3(av_codec);
    //根据所提供的编解码器的值填充编译码上下文
    int avcodec_to_context = avcodec_parameters_to_context(av_codec_ctx,av_codec_pm);
    if(avcodec_to_context < 0){
        return;
    }
    int av_codec_open_result = avcodec_open2(av_codec_ctx, av_codec, NULL);
    if (av_codec_open_result != 0) {
        LOG_I("解码器打开失败!");
        return;
    }
    //从输入文件读取一帧压缩数据
    //循环遍历
    //保存一帧读取的压缩数据-(提供缓冲区)
        packet = (AVPacket *) av_malloc(sizeof(AVPacket));
    //内存分配
        in_frame = av_frame_alloc();
    //定义上下文(开辟内存)
        swr_ctx = swr_alloc();
    //设置音频采样上下文参数(例如:码率、采样率、采样格式、输出声道等等......)
    //swr_alloc_set_opts参数分析如下
    //参数一:音频采样上下文
    //参数二:输出声道布局(例如:立体、环绕等等......)
    //立体声
    uint64_t out_ch_layout = AV_CH_LAYOUT_STEREO;
    //参数三:输出音频采样格式(采样精度)
    AVSampleFormat av_sm_fm = AV_SAMPLE_FMT_S16;
    //参数四:输出音频采样率(例如:44100Hz、48000Hz等等......)
    //在这里需要注意:保证输出采样率和输入的采样率保证一直(如果你不想一直,你可进行采样率转换)
    int out_sample_rate = av_codec_ctx->sample_rate;
    //输入声道布局
    int64_t in_ch_layout = av_get_default_channel_layout(av_codec_ctx->channels);
    //参数六:输入音频采样格式(采样精度)
    //参数七:输入音频采样率(例如:44100Hz、48000Hz等等......)
    //参数八:偏移量
    //参数九:日志统计上下文
    swr_alloc_set_opts(swr_ctx,
                       out_ch_layout,
                       av_sm_fm,
                       out_sample_rate,
                       in_ch_layout,
                       av_codec_ctx->sample_fmt,
                       av_codec_ctx->sample_rate,
                       0,
                       NULL);
    //初始化音频采样数据上下文
    swr_init(swr_ctx);
    //音频采样数据缓冲区(每一帧大小)
    //44100 16bit  大小: size = 44100 * 2 / 1024 = 86KB
    //最大采样率
        out_buffer = (uint8_t *) av_malloc(MAX_AUDIO_FRAME_SIZE);
    //获取输出声道数量(根据声道布局获取对应的声道数量)
    int out_nb_channels = av_get_channel_layout_nb_channels(out_ch_layout);
    //大于等于0,继续读取,小于0说明读取完毕或者读取失败
    int ret, index = 0;
    while (av_read_frame(av_fm_ctx, packet) >= 0) {
        //解码一帧音频压缩数据得到音频采样数据
        if (packet->stream_index == audio_stream_index) {
            //解码一帧音频压缩数据,得到一帧音频采样数据
            //0:表示成功(成功解压一帧音频压缩数据)
            //AVERROR(EAGAIN): 现在输出数据不可用,可以尝试发送一帧新的视频压缩数据(或者说尝试解压下一帧视频压缩数据)
            //AVERROR_EOF:解码完成,没有新的视频压缩数据
            //AVERROR(EINVAL):当前是一个编码器,但是编解码器未打开
            //AVERROR(ENOMEM):解码一帧视频压缩数据发生异常
            avcodec_send_packet(av_codec_ctx, packet);
            //返回值解释:
            //0:表示成功(成功获取一帧音频采样数据)
            //AVERROR(EAGAIN): 现在输出数据不可用,可以尝试接受一帧新的视频像素数据(或者说尝试获取下一帧视频像素数据)
            //AVERROR_EOF:接收完成,没有新的视频像素数据了
            //AVERROR(EINVAL):当前是一个编码器,但是编解码器未打开
            ret = avcodec_receive_frame(av_codec_ctx, in_frame);
            if (ret == 0) {
                //将音频采样数据保存(写入到文件中)
                //音频采样数据格式是:PCM格式、采样率(44100Hz)、16bit
                //对音频采样数据进行转换为PCM格式
                //参数一:音频采样上下文
                //参数二:输出音频采样缓冲区
                //参数三:输出缓冲区大小
                //参数四:输入音频采样数据
                //参数五:输入音频采样数据大小
                swr_convert(swr_ctx,
                            &out_buffer,
                            MAX_AUDIO_FRAME_SIZE,
                            (const uint8_t **) in_frame->data, in_frame->nb_samples);

                //获取缓冲区实际数据大小
                //参数一:行大小
                //参数二:输出声道个数
                //参数三:输入的大小
                //参数四:输出的音频采样数据格式
                //参数五:字节对齐
               int out_buffer_size = av_samples_get_buffer_size(NULL,
              out_nb_channels,in_frame->nb_samples,av_sm_fm, 1);
                //写入到文件中
                fwrite(out_buffer, 1, (size_t) out_buffer_size, out);
                LOG_I_ARGS("音频帧:%d\n", ++index);
            }
        }
    }
    swr_close(swr_ctx);
    swr_free(&swr_ctx);
    av_frame_free(&in_frame);
    avcodec_parameters_free(&av_codec_pm);
    avcodec_close(av_codec_ctx);
    avcodec_free_context(&av_codec_ctx);
}

/**
 * 音频编码
 * @param path PCM文件地址
 * @param out 输出文件地址
 */
void encoder(const char* path,const char* out){
    //打开 pcm,MP3文件
    FILE* fpcm = fopen(path,"rb");
    FILE* fmp3 = fopen(out,"wb");
    short int pcm_buffer[8192*2];
    unsigned char mp3_buffer[8192];
    //初始化lame的编码器
    lame_t lame =  lame_init();
    //设置lame mp3编码的采样率
    lame_set_in_samplerate(lame , 44100);
    lame_set_num_channels(lame,2);
    //设置MP3的编码方式
    lame_set_VBR(lame, vbr_default);
    lame_init_params(lame);
    LOG_I("lame init finish");
    int read ; int write; //代表读了多少个次 和写了多少次
    int total=0; // 当前读的wav文件的byte数目
    do{
        read = fread(pcm_buffer,sizeof(short int)*2, 8192,fpcm);
        total +=  read* sizeof(short int)*2;
        LOG_I_ARGS("converting ....%d", total);

        // 调用java代码 完成进度条的更新
        if(read!=0){
            write = lame_encode_buffer_interleaved(lame,pcm_buffer,read,mp3_buffer,8192);
            //把转化后的mp3数据写到文件里
            fwrite(mp3_buffer,sizeof(unsigned char),write,fmp3);
        }
        if(read==0){
            lame_encode_flush(lame,mp3_buffer,8192);
        }
    }while(read!=0);
    LOG_I("convert  finish");
    lame_close(lame);
    fclose(fpcm);
    fclose(fmp3);
}
  static {
        System.loadLibrary("native-lib");
    }
   /**
     * 拼接音频
     * @param paths 音频地址集合
     * @param path 采样数据地址
     * @param out 编码数据地址
     */  
 public native void jointAudio(String[]paths,String path,String out);

  public void jointAudioClick(View view) {
        List<String> audioList = new ArrayList<String>();
        audioList.add(path+"0.mp3");
        audioList.add(path+"1.wav");
        audioList.add(path+"2.aac");
        new Thread(new Runnable() {
                @Override
                public void run() { 
            jointAudio(finalPaths,target,path+"eng100.mp3");  
                }
            }).start();
            }

第二种情况,相同格式音频拼接,只需要字节流拼接即可,当然如果不嫌效率低也可以选用以上两种方式进行拼接。(注意:音频的声道数需要一致,我开发遇到把单声道和立体声拼接到一块,会使得音频时间成倍增加,各位请注意。)

 public void jointAudio(String audioPath, String toPath)throws Exception {
        File audioFile = new File(audioPath);
        File toFile = new File(toPath);
        FileInputStream in=new FileInputStream(audioFile);
        FileOutputStream out=new FileOutputStream(toFile,true);

        byte bs[]=new byte[1024*4];
        int len=0;
        //先读第一个
        while((len=in.read(bs))!=-1){
            out.write(bs,0,len);
        }
        in.close();
        out.close();
    }
 public void jointAudioClick(View view) {
        List<String> audioList = new ArrayList<String>();
        audioList.add(path+"0.mp3");
        audioList.add(path+"1.mp3");
        audioList.add(path+"2.mp3");
        new Thread(new Runnable() {
                @Override
                public void run() { 
            try {
               for (String audioPath : audioList) {
                  //拼接
                  jointAudio(audioPath, path + "eng100100.mp3");
                  }catch (Exception ex){
                    ex.printStackTrace();
                  }
                }
            }).start();
            }

本文章著作版权所属:微笑面对,请关注我的CSDN博客:博客地址

2017-09-26 19:23:40 kris__fu 阅读数 233

android bitmap拼接

一个简单的拼接方法

//bitmaps 需要拼接的图片,按顺序传入

public static Bitmap mosaicBitmapVertical(@NonNull Bitmap... bitmaps) {

    int height = 0;
    for (int i = 0; i < bitmaps.length; i++) {
        height += bitmaps[i].getHeight();
    }
    int width = 0;
    for (int i = 0; i < bitmaps.length; i++) {
        if (width < bitmaps[i].getWidth()) {
            width = bitmaps[i].getWidth();
        }
    }
    Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    int drawHeight = 0;
    for (int i = 0; i < bitmaps.length; i++) {
        canvas.drawBitmap(bitmaps[i],0,drawHeight,null);
        drawHeight += bitmaps[i].getHeight();
    }
    return result;
}

这个是竖直拼接,水平拼接照着简单改一下就好

没有更多推荐了,返回首页