当前位置: 首页 > news >正文

网站建设验收条款巩义网站优化公司

网站建设验收条款,巩义网站优化公司,空包自己可以做物流信息的网站,德阳市建设管理一体化平台网站效果图全部正确:有对有错:结果展示,纯黑色:支持图片:实现思路仔细分析可以发现,连线题的布局可以分为两部分,一个是左右两列矩形,另一个是他们之间的连线。每个矩形的宽高都一样&…

效果图

全部正确:

有对有错:

结果展示,纯黑色:

支持图片:

实现思路

仔细分析可以发现,连线题的布局可以分为两部分,一个是左右两列矩形,另一个是他们之间的连线。

每个矩形的宽高都一样,或者等比例,这样利于给他们定位,添加矩形时使用ViewGroup#ddView(View child, LayoutParams params)方法,我们通过LayoutParams参数来控制每个矩形的位置。

为了方便添加矩形,这里我们的自定义布局继承自RelativeLayout。

public class LinkLineView extends RelativeLayout {...
}

接下来说连线,连线我们通过记录他们的起点和终点数据,然后调用View#invalidate方法,在ViewGgroup#dispatchDraw()方法里面通过canvas.drawLine()方法进行绘制。

我们假设线都是从左向右连的,起点就是左边矩形右边距的中点,终点就是右边矩形左边距的中点。在添加矩形的时候我们可以知道每个矩形的具体参数,所以所有连线的起点和终点的数据我们是知道的,接着就是如何表示一根线的问题。

在所有连线完成之前,连线是可以取消掉的;在所有连线完成后,我们需要用连线结果跟正确结果进行比对的,所以我们需要针对每次连线定义一个数据结构,具体如下:

public class LinkLineBean {/*** 直线的横纵坐标*/private float startX;private float startY;private float endX;private float endY;public LinkLineBean(float startX, float startY, float endX, float endY) {this.startX = startX;this.startY = startY;this.endX = endX;this.endY = endY;}// 省略getter和setter方法@Overridepublic boolean equals(Object o) {if (this == o) {return true;}if (!(o instanceof LinkLineBean)) {return false;}LinkLineBean that = (LinkLineBean) o;return (Float.compare(that.startX, startX) == 0 &&Float.compare(that.startY, startY) == 0 &&Float.compare(that.endX, endX) == 0 &&Float.compare(that.endY, endY) == 0)|| (Float.compare(that.startX, endX) == 0 &&Float.compare(that.startY, endY) == 0 &&Float.compare(that.endX, startX) == 0 &&Float.compare(that.endY, startY) == 0);}@Overridepublic int hashCode() {return Objects.hash(startX, startY, endX, endY);}
}

这里省略了一些不必要的代码。

重写equals和hashCode方法是为了比较是否是同一条连线。如果连线A的起点等于连线B的终点,连线A的终点等于连线B的起点,我们就认为他们是同一条连线,这个也符合我们的常识,同一条线从左向右连和从右向左连是一样的。

核心思路说完了,剩下的就是一些细节处理了。

源码实现

连线题父容器

/*** @Description: 连线题的父容器* @Version*/
public class LinkLineView extends RelativeLayout {private static final String TAG = LinkLineView.class.getSimpleName();private Context context;private List<LinkDataBean> allList = new ArrayList<>();private List<LinkDataBean> leftList = new ArrayList<>();private List<LinkDataBean> rightList = new ArrayList<>();private int size;private int cellHeight;private int cellWidth;private int marginLeft;private int marginRight;private int marginBottom;private List<View> leftTvs = new ArrayList<>();private List<View> rightTvs = new ArrayList<>();boolean leftSelected;boolean rightSelected;View tvLeftSelected;View tvRightSelected;private List<LinkLineBean> linkLineBeanList = new ArrayList<>();private List<LinkLineBean> newLinkLineBeanList = new ArrayList<>();// 是否可点击private boolean isEnabled = true;private OnChoiceResultListener onChoiceResultListener;private boolean analysisMode;public LinkLineView(@NonNull Context context) {super(context);init(context);}public LinkLineView(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);init(context);}public LinkLineView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context);}@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)public LinkLineView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);init(context);}public void setOnChoiceResultListener(OnChoiceResultListener onChoiceResultListener) {this.onChoiceResultListener = onChoiceResultListener;}private void init(Context context) {this.context = context;}/*** 练习** @param linkDataBeanList*/public void setData(List<LinkDataBean> linkDataBeanList) {if (linkDataBeanList == null || linkDataBeanList.size() == 0) {return;}this.allList = linkDataBeanList;// 将数据分为两列for (LinkDataBean item : allList) {if (0 == item.getCol()) {leftList.add(item);} else {rightList.add(item);}}// 将数据根据行号排序,避免数据错乱Collections.sort(leftList, (o1, o2) -> o1.getRow() - o2.getRow());Collections.sort(rightList, (o1, o2) -> o1.getRow() - o2.getRow());LogUtils.e(TAG, "leftList:" + leftList);LogUtils.e(TAG, "rightList:" + rightList);size = Math.min(leftList.size(), rightList.size());// 是否是图片类型,图片类型的话,高度跟TextView不一致boolean isImageType = false;for (LinkDataBean item : linkDataBeanList) {if ("1".equals(item.getType())) {isImageType = true;break;}}float ratioW = 0.0f;if (isImageType) {ratioW = 400 / 1080.0f;cellWidth = (int) (ScreenUtils.getScreenW(context) * ratioW);cellHeight = (int) (cellWidth * 280 / 400.0f);} else { // TextView类型ratioW = 400 / 1080.0f;cellWidth = (int) (ScreenUtils.getScreenW(context) * ratioW);cellHeight = (int) (cellWidth * 180 / 400.0f);}marginLeft = 0;marginRight = 0;marginBottom = ScreenUtils.dip2px(context, 20);addLeftView();addRightView();}/*** 练习* 全部黑色** @param linkDataBeanList*/public void justShowResult(List<LinkDataBean> linkDataBeanList) {this.analysisMode = true;setData(linkDataBeanList);// view绘制完成后才能获取到宽高this.post(() -> {List<LinkLineBean> resultList = getResultList();// 禁止点击事件isEnabled = false;newLinkLineBeanList = new ArrayList<>();for (int i = 0; i < resultList.size(); i++) {// 改变连线的颜色resultList.get(i).setColorString(LinkLineBean.COLOR_BLACK);// 改变边框的颜色leftTvs.get(i).setBackground(context.getResources().getDrawable(R.drawable.bg_black_round_10dp));if (leftTvs.get(i) instanceof RoundedImageView) {((RoundedImageView) leftTvs.get(i)).setBorderColor(Color.BLACK);}rightTvs.get(i).setBackground(context.getResources().getDrawable(R.drawable.bg_black_round_10dp));if (rightTvs.get(i) instanceof RoundedImageView) {((RoundedImageView) rightTvs.get(i)).setBorderColor(Color.BLACK);}newLinkLineBeanList.add(resultList.get(i));}invalidate();});}private void addLeftView() {for (int i = 0; i < leftList.size(); i++) {LinkDataBean bean = leftList.get(i);View view;if ("1".equals(bean.getType())) {view = generateImageView(bean);} else {view = generateTextView(bean);}OnClickListener onClickListener = v -> {if (analysisMode) {return;}if (!isEnabled) {return;}if (tvLeftSelected != v) {resetLeftTvStatus();}v.setSelected(true);if (v instanceof RoundedImageView) {((RoundedImageView) v).setBorderColor(Color.parseColor("#1391EB"));}leftSelected = true;tvLeftSelected = v;if (rightSelected) {resetTvStatus();drawLinkLine();}};view.setOnClickListener(onClickListener);// 布局LayoutParams lp = new LayoutParams(cellWidth, cellHeight);lp.leftMargin = marginLeft;lp.topMargin = i * (cellHeight + marginBottom);addView(view, lp);leftTvs.add(view);}}private void addRightView() {for (int i = 0; i < rightList.size(); i++) {LinkDataBean bean = rightList.get(i);View view;if ("1".equals(bean.getType())) {view = generateImageView(bean);} else {view = generateTextView(bean);}OnClickListener onClickListener = v -> {if (analysisMode) {return;}if (!isEnabled) {return;}if (tvRightSelected != v) {resetRightTvStatus();}v.setSelected(true);if (v instanceof RoundedImageView) {((RoundedImageView) v).setBorderColor(Color.parseColor("#1391EB"));}rightSelected = true;tvRightSelected = v;if (leftSelected) {resetTvStatus();drawLinkLine();}};view.setOnClickListener(onClickListener);// 布局LayoutParams lp = new LayoutParams(cellWidth, cellHeight);lp.rightMargin = marginRight;lp.topMargin = i * (cellHeight + marginBottom);lp.addRule(ALIGN_PARENT_RIGHT);addView(view, lp);rightTvs.add(view);}}private void resetLeftTvStatus() {for (View item : leftTvs) {item.setSelected(false);if (item instanceof RoundedImageView) {((RoundedImageView) item).setBorderColor(Color.TRANSPARENT);}}}private void resetRightTvStatus() {for (View item : rightTvs) {item.setSelected(false);if (item instanceof RoundedImageView) {((RoundedImageView) item).setBorderColor(Color.TRANSPARENT);}}}private void resetTvStatus() {resetLeftTvStatus();resetRightTvStatus();}/*** 绘制连线*/private void drawLinkLine() {if (tvLeftSelected == null || tvRightSelected == null) {return;}// 从TextView上获取对应的坐标,进而确定连线的起点和终点的位置float startX = tvLeftSelected.getRight();float startY = (tvLeftSelected.getTop() + tvLeftSelected.getBottom()) / 2.0f;float endX = tvRightSelected.getLeft();float endY = (tvRightSelected.getTop() + tvRightSelected.getBottom()) / 2.0f;LogUtils.e(TAG, "startX:" + startX + ", startY:" + startY + ", endX:" + endX + ", endY:" + endY);if (linkLineBeanList == null) {linkLineBeanList = new ArrayList<>();}LogUtils.e(TAG, "before remove:" + linkLineBeanList);newLinkLineBeanList = new ArrayList<>();for (LinkLineBean item : linkLineBeanList) {newLinkLineBeanList.add(item);}// 在已绘制好的连线中,去除起点或终点相同的线Iterator<LinkLineBean> iterator = newLinkLineBeanList.iterator();while (iterator.hasNext()) {LinkLineBean bean = iterator.next();if (bean != null) {if ((startX == bean.getStartX() && startY == bean.getStartY())|| (startX == bean.getEndX() && startY == bean.getEndY())|| (endX == bean.getStartX() && endY == bean.getStartY())|| (endX == bean.getEndX() && endY == bean.getEndY())) {iterator.remove();}}}LogUtils.e(TAG, "after remove:" + newLinkLineBeanList);LinkLineBean bean = new LinkLineBean(startX, startY, endX, endY);int leftIndex = -1;for (int i = 0; i < leftTvs.size(); i++) {if (tvLeftSelected == leftTvs.get(i)) {leftIndex = i;break;}}bean.setLeftIndex(leftIndex);int rightIndex = -1;for (int i = 0; i < rightTvs.size(); i++) {if (tvRightSelected == rightTvs.get(i)) {rightIndex = i;break;}}bean.setRightIndex(rightIndex);newLinkLineBeanList.add(bean);LogUtils.e(TAG, "after add:" + newLinkLineBeanList);// 重置临时变量状态leftSelected = false;rightSelected = false;tvLeftSelected = null;tvRightSelected = null;// 检查是否所有连线均已完成if (newLinkLineBeanList.size() >= size) {isEnabled = false;verifyResult();}// 触发dispatchDraw方法,绘制连线invalidate();}private void verifyResult() {/*** 更新UI,标记出正确的和错误的连线*/drawSelectedLinkLine();boolean isRight = true;for (LinkLineBean item : newLinkLineBeanList) {if (!item.isRight()) {isRight = false;break;}}String yourAnswer = "";if (!ListUtils.isEmpty(newLinkLineBeanList)) {Type type = new TypeToken<ArrayList<LinkLineBean>>() {}.getType();try {yourAnswer = new Gson().toJson(newLinkLineBeanList, type);} catch (Exception e) {e.printStackTrace();}}if (onChoiceResultListener != null) {onChoiceResultListener.onResultSelected(isRight, yourAnswer);}}/*** 将选择的结果绘制出来,有对有错那种*/private void drawSelectedLinkLine() {List<LinkLineBean> resultList = getResultList();LogUtils.e(TAG, "resultList:" + resultList);for (int i = 0; i < newLinkLineBeanList.size(); i++) {newLinkLineBeanList.get(i).setRight(resultList.contains(newLinkLineBeanList.get(i)));// 改变连线的颜色newLinkLineBeanList.get(i).setColorString(newLinkLineBeanList.get(i).isRight() ? LinkLineBean.COLOR_RIGHT : LinkLineBean.COLOR_WRONG);// 改变边框的颜色int leftIndex = newLinkLineBeanList.get(i).getLeftIndex();if (leftIndex >= 0 && leftIndex < leftTvs.size()) {leftTvs.get(leftIndex).setBackground(context.getResources().getDrawable(newLinkLineBeanList.get(i).isRight() ? R.drawable.bg_link_line_green : R.drawable.bg_link_line_red));if (leftTvs.get(leftIndex) instanceof RoundedImageView) {((RoundedImageView) leftTvs.get(leftIndex)).setBorderColor(newLinkLineBeanList.get(i).isRight() ? ContextCompat.getColor(context, R.color.answer_right) : ContextCompat.getColor(context, R.color.answer_wrong));}}int rightIndex = newLinkLineBeanList.get(i).getRightIndex();if (rightIndex >= 0 && rightIndex < rightTvs.size()) {rightTvs.get(rightIndex).setBackground(context.getResources().getDrawable(newLinkLineBeanList.get(i).isRight() ? R.drawable.bg_link_line_green : R.drawable.bg_link_line_red));if (rightTvs.get(rightIndex) instanceof RoundedImageView) {((RoundedImageView) rightTvs.get(rightIndex)).setBorderColor(newLinkLineBeanList.get(i).isRight() ? ContextCompat.getColor(context, R.color.answer_right) : ContextCompat.getColor(context, R.color.answer_wrong));}}}}/*** 获取正确的连线数据** @return*/private List<LinkLineBean> getResultList() {List<LinkLineBean> resultList = new ArrayList<>(size);for (int i = 0; i < leftTvs.size(); i++) {// 从TextView上获取对应的起点坐标float startX = leftTvs.get(i).getRight();float startY = (leftTvs.get(i).getTop() + leftTvs.get(i).getBottom()) / 2.0f;LinkDataBean leftBean = leftList.get(i);for (int j = 0; j < rightList.size(); j++) {if (leftBean.getQ_num() == rightList.get(j).getQ_num()) {float endX = rightTvs.get(j).getLeft();float endY = (rightTvs.get(j).getTop() + rightTvs.get(j).getBottom()) / 2.0f;LinkLineBean linkLineBean = new LinkLineBean(startX, startY, endX, endY);resultList.add(linkLineBean);}}}return resultList;}private TextView generateTextView(LinkDataBean bean) {TextView textView = new TextView(context);textView.setTextColor(ContextCompat.getColor(context, R.color.black));textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);textView.setGravity(Gravity.CENTER);textView.setMaxLines(2);textView.setEllipsize(TextUtils.TruncateAt.END);textView.setBackground(context.getResources().getDrawable(R.drawable.selector_link_line));textView.setTag(bean.getQ_num());textView.setText(bean.getContent());return textView;}private RoundedImageView generateImageView(LinkDataBean bean) {RoundedImageView riv = new RoundedImageView(context);riv.setScaleType(ImageView.ScaleType.CENTER_CROP);riv.setCornerRadius(ScreenUtils.dip2px(context, 10));riv.setBorderWidth(ScreenUtils.dip2px(context, 2) * 1.0f);riv.setBorderColor(Color.TRANSPARENT);riv.mutateBackground(true);riv.setImageDrawable(context.getResources().getDrawable(R.drawable.selector_link_line));Glide.with(riv).load(bean.getContent()).into(riv);return riv;}@Overrideprotected void dispatchDraw(Canvas canvas) {super.dispatchDraw(canvas);LogUtils.e(TAG, "dispatchDraw");if (linkLineBeanList == null) {linkLineBeanList = new ArrayList<>();}if (newLinkLineBeanList == null) {newLinkLineBeanList = new ArrayList<>();}// 先清除掉原有绘制的线for (LinkLineBean item : linkLineBeanList) {if (item != null) {Paint paint = new Paint();paint.setColor(Color.TRANSPARENT);paint.setStrokeWidth(ScreenUtils.dip2px(context, 2));canvas.drawLine(item.getStartX(), item.getStartY(), item.getEndX(), item.getEndY(), paint);}}for (LinkLineBean item : newLinkLineBeanList) {if (item != null) {Paint paint = new Paint();paint.setColor(Color.parseColor(item.getColorString()));paint.setStrokeWidth(ScreenUtils.dip2px(context, 2));canvas.drawLine(item.getStartX(), item.getStartY(), item.getEndX(), item.getEndY(), paint);}}linkLineBeanList.clear();for (LinkLineBean item : newLinkLineBeanList) {linkLineBeanList.add(item);}}public interface OnChoiceResultListener {void onResultSelected(boolean correct, String yourctAnswer);}
}

文本连线Activity

public class LinkLineTextActivity extends AppCompatActivity {@BindView(R.id.link_line_view)LinkLineView linkLineView;@BindView(R.id.fl_link_line)FrameLayout flLinkLine;@BindView(R.id.tv_result)TextView tvResult;public static void actionStart(Context context) {Intent starter = new Intent(context, LinkLineTextActivity.class);context.startActivity(starter);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_link_line_text);ButterKnife.bind(this);List<LinkDataBean> list = MockDataUtil.getInstance().mockLinkLineData(this, 0);linkLineView.setData(list);linkLineView.setOnChoiceResultListener((correct, yourAnswer) -> {// 结果StringBuilder sb = new StringBuilder();sb.append("正确与否:");sb.append(correct);sb.append("\n");tvResult.setText(sb.toString());});}
}

图片连线Activity

public class LinkLineImageActivity extends AppCompatActivity {@BindView(R.id.link_line_view)LinkLineView linkLineView;@BindView(R.id.fl_link_line)FrameLayout flLinkLine;@BindView(R.id.tv_result)TextView tvResult;public static void actionStart(Context context) {Intent starter = new Intent(context, LinkLineImageActivity.class);context.startActivity(starter);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_link_line_image);ButterKnife.bind(this);List<LinkDataBean> list = MockDataUtil.getInstance().mockLinkLineData(this, 1);linkLineView.setData(list);linkLineView.setOnChoiceResultListener((correct, yourAnswer) -> {// 结果StringBuilder sb = new StringBuilder();sb.append("正确与否:");sb.append(correct);sb.append("\n");tvResult.setText(sb.toString());});}
}

ModeActivity

public class LinkLineShowModeActivity extends AppCompatActivity {@BindView(R.id.link_line_view)LinkLineView linkLineView;@BindView(R.id.fl_link_line)FrameLayout flLinkLine;public static void actionStart(Context context) {Intent starter = new Intent(context, LinkLineShowModeActivity.class);context.startActivity(starter);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_link_line_show_mode);ButterKnife.bind(this);List<LinkDataBean> list = MockDataUtil.getInstance().mockLinkLineData(this,0);linkLineView.justShowResult(list);}
}

MainActivity

public class MainActivity extends AppCompatActivity {@BindView(R.id.btn_0)Button btn0;@BindView(R.id.btn_1)Button btn1;@BindView(R.id.btn_2)Button btn2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);}@OnClick({R.id.btn_0, R.id.btn_1, R.id.btn_2})public void onViewClicked(View view) {switch (view.getId()) {case R.id.btn_0:LinkLineTextActivity.actionStart(MainActivity.this);break;case R.id.btn_1:LinkLineImageActivity.actionStart(MainActivity.this);break;case R.id.btn_2:LinkLineShowModeActivity.actionStart(MainActivity.this);break;}}
}

连线原数据

/*** @Description: 连线的原数据* @Version*/
public class LinkDataBean {/*** content : chair* q_num : 0* type : 0* col : 0* row : 0*/private String content;private int q_num;/*** 0:text文本* 1:图片*/private String type;private int col;private int row;public String getContent() {return content;}public void setContent(String content) {this.content = content;}public int getQ_num() {return q_num;}public void setQ_num(int q_num) {this.q_num = q_num;}public String getType() {return type;}public void setType(String type) {this.type = type;}public int getCol() {return col;}public void setCol(int col) {this.col = col;}public int getRow() {return row;}public void setRow(int row) {this.row = row;}@Overridepublic String toString() {return "LinkDataBean{" +"content='" + content + '\'' +", q_num=" + q_num +", type='" + type + '\'' +", col=" + col +", row=" + row +'}';}
}

LinkLine对象

/*** @Description: 表示LinkLine对象* @Version*/
public class LinkLineBean {public static final String COLOR_BLACK = "#ff000000";public static final String COLOR_BLUE = "#1391EB";public static final String COLOR_RIGHT = "#ff00deab";public static final String COLOR_WRONG = "#ffff7c64";/*** 直线的横纵坐标*/private float startX;private float startY;private float endX;private float endY;private String colorString = COLOR_BLUE;private boolean isRight;private int leftIndex = -1;private int rightIndex = -1;public LinkLineBean(float startX, float startY, float endX, float endY) {this.startX = startX;this.startY = startY;this.endX = endX;this.endY = endY;}public float getStartX() {return startX;}public void setStartX(float startX) {this.startX = startX;}public float getStartY() {return startY;}public void setStartY(float startY) {this.startY = startY;}public float getEndX() {return endX;}public void setEndX(float endX) {this.endX = endX;}public float getEndY() {return endY;}public void setEndY(float endY) {this.endY = endY;}public String getColorString() {return colorString;}public void setColorString(String colorString) {this.colorString = colorString;}public boolean isRight() {return isRight;}public void setRight(boolean right) {isRight = right;}public int getLeftIndex() {return leftIndex;}public void setLeftIndex(int leftIndex) {this.leftIndex = leftIndex;}public int getRightIndex() {return rightIndex;}public void setRightIndex(int rightIndex) {this.rightIndex = rightIndex;}@Overridepublic String toString() {return "LinkLineBean{" +"startX=" + startX +", startY=" + startY +", endX=" + endX +", endY=" + endY +", colorString='" + colorString + '\'' +", isRight=" + isRight +", leftIndex=" + leftIndex +", rightIndex=" + rightIndex +'}';}@Overridepublic boolean equals(Object o) {if (this == o) {return true;}if (!(o instanceof LinkLineBean)) {return false;}LinkLineBean that = (LinkLineBean) o;return (Float.compare(that.startX, startX) == 0 &&Float.compare(that.startY, startY) == 0 &&Float.compare(that.endX, endX) == 0 &&Float.compare(that.endY, endY) == 0)|| (Float.compare(that.startX, endX) == 0 &&Float.compare(that.startY, endY) == 0 &&Float.compare(that.endX, startX) == 0 &&Float.compare(that.endY, startY) == 0);}@Overridepublic int hashCode() {return Objects.hash(startX, startY, endX, endY);}
}

数据工具类

/*** @Description: 模拟数据的* @Version*/
public class MockDataUtil {private MockDataUtil() {}private static final class MockDataUtilHolder {private static final MockDataUtil INSTANCE = new MockDataUtil();}public static MockDataUtil getInstance() {return MockDataUtilHolder.INSTANCE;}/*** 从assets中读取对应的json文件** @param context* @param assetsName* @return*/private String getJsonFromAssets(Context context, String assetsName) {if (TextUtils.isEmpty(assetsName)) {return null;}String jsonString = "";try {StringBuffer sb = new StringBuffer();InputStream is = null;is = context.getAssets().open(assetsName);int len = -1;byte[] buf = new byte[is.available()];//为了解决部分中文乱码问题,一次读取所有的while ((len = is.read(buf)) != -1) {sb.append(new String(buf, 0, len, "UTF-8"));}is.close();jsonString = sb.toString();} catch (IOException e) {e.printStackTrace();}return jsonString;}public List<LinkDataBean> mockLinkLineData(Context context, int index) {if (context == null) {return null;}List<LinkDataBean> mockResp = new ArrayList<>();StringBuilder sb = new StringBuilder("linkline/data_json");sb.append(index);sb.append(".json");if (!TextUtils.isEmpty(sb.toString())) {String jsonString = getJsonFromAssets(context, sb.toString());Type type = new TypeToken<ArrayList<LinkDataBean>>() {}.getType();try {mockResp = new Gson().fromJson(jsonString, type);} catch (JsonSyntaxException e) {e.printStackTrace();}}return mockResp;}
}

XML布局

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/btn_0"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:text="文字连线题"android:textAllCaps="false"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/btn_1"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:text="图片连线题"android:textAllCaps="false"app:layout_constraintTop_toBottomOf="@+id/btn_0" /><Buttonandroid:id="@+id/btn_2"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:text="连线题——纯展示模式"android:textAllCaps="false"app:layout_constraintTop_toBottomOf="@+id/btn_1" /></androidx.constraintlayout.widget.ConstraintLayout>

activity_link_line_text.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><FrameLayoutandroid:id="@+id/fl_link_line"android:layout_marginTop="20dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="10.0dip"android:background="#fff"android:paddingLeft="13.0dip"android:paddingRight="13.0dip"android:paddingBottom="20.0dip"app:layout_constraintTop_toTopOf="parent"><com.tinytongtong.linklinedemo.LinkLineViewandroid:id="@+id/link_line_view"android:layout_width="fill_parent"android:layout_height="wrap_content" /></FrameLayout><TextViewandroid:id="@+id/tv_result"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="20dp"app:layout_constraintTop_toBottomOf="@+id/fl_link_line" /></androidx.constraintlayout.widget.ConstraintLayout></androidx.core.widget.NestedScrollView>

activity_link_line_show_mode.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><FrameLayoutandroid:id="@+id/fl_link_line"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:layout_marginBottom="10.0dip"android:background="#fff"android:paddingLeft="13.0dip"android:paddingRight="13.0dip"android:paddingBottom="20.0dip"app:layout_constraintTop_toTopOf="parent"><com.tinytongtong.linklinedemo.LinkLineViewandroid:id="@+id/link_line_view"android:layout_width="fill_parent"android:layout_height="wrap_content" /></FrameLayout><TextViewandroid:id="@+id/tv_result"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="20dp"app:layout_constraintTop_toBottomOf="@+id/fl_link_line" /></androidx.constraintlayout.widget.ConstraintLayout></androidx.core.widget.NestedScrollView>

activity_link_line_image.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><FrameLayoutandroid:id="@+id/fl_link_line"android:layout_marginTop="20dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="10.0dip"android:background="#fff"android:paddingLeft="13.0dip"android:paddingRight="13.0dip"android:paddingBottom="20.0dip"app:layout_constraintTop_toTopOf="parent"><com.tinytongtong.linklinedemo.LinkLineViewandroid:id="@+id/link_line_view"android:layout_width="fill_parent"android:layout_height="wrap_content" /></FrameLayout><TextViewandroid:id="@+id/tv_result"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="20dp"app:layout_constraintTop_toBottomOf="@+id/fl_link_line" /></androidx.constraintlayout.widget.ConstraintLayout></androidx.core.widget.NestedScrollView>

源码地址

https://github.com/tinyvampirepudge/LinkLineDemo
http://www.dt0577.cn/news/3086.html

相关文章:

  • 网站建设工期时间表关键词怎么优化到百度首页
  • 新疆美食网站建设前的市场分析搜索引擎网站大全
  • 鞍山吧台杭州百度优化
  • Wordpress全站404seo关键词排优化软件
  • 做资料分享网站有哪些青岛seo关键词优化排名
  • wordpress模版 使用教程网站优化的意义
  • 那些是flash做的网站常用网站推广方法及资源
  • 制作图片的app免费网络推广优化招聘
  • 为什么用花生壳做的网站老刷新网站查询网
  • ibm用来做测试的网站宿迁网站建设制作
  • 用word做网站功能结构图个人做外贸怎样起步
  • 网站开发岗位职责黄山网站seo
  • 电子商务网站建设与安全百度推广工具
  • 住房与城乡建设部windows系统优化软件
  • 网站开发发现趋势营销渠道策略
  • 洛阳做网站推广推广运营
  • 福州专业做网站cpv广告联盟
  • 电子商务网站规划与设计网页设计个人主页
  • 做牛仔裤的视频网站免费建网站的步骤
  • 织梦网站首页模板更换免费关键词搜索引擎工具
  • 外链生成器优化大师win10下载
  • 2017两学一做网站免费推广网站地址大全
  • 做团购的的网站有哪些网站关键词优化wang
  • 专门 做鞋子团购的网站中国行业数据分析网
  • 通辽网站建设0475seo广东seo推广费用
  • 湖南建筑一体化平台seo的优点
  • 营销型网站建设哪好国际最新消息
  • php做网站需要的软件朋友圈推广文案
  • 肇庆做网站的有刚刚中国突然宣布
  • 淘客网站怎么做生成关键词的软件免费