【需求解决系列之一】移动卡片实现答题功能,kotlin第三方库

计算当前“单词块”的中心点和”题干“中的哪两个单词的中间的”缝“最近 其实这里有两种思路,一种通过RecyclerView的适配器获取到每个item的位置信息,然后计算出两个item的中间位置,将所有的这些中间位置保存起来,在分别计算“单词块”的中心点和这些中间位置的距离,然后再处理,不过用这种方式需要考虑item换行之后中心点计算的问题(由于我没有使用这种方式,对这个预期会出现的问题也没有多加思考);还有一种是在创建题干的时候使用多类型的适配器,在每个单词中间插入一个占位置的”空格“,这样就可以直接获取到这个”空格“的位置作为参照点,同时,这个空格还可以直接给用户提示位置,一举两得。我这里就是用的第二种方式。

找出最近的”缝“

//找出最近的点 只找没有内容的格子 就是占位格子
private ItemPositionModel findPoint() {
//没有数据直接返回
if ( itemList.isEmpty() )
return null;
double distance = Math.sqrt(Math.pow((center.x - itemList.get(0).getCenter().x), 2) +
Math.pow((center.y - itemList.get(0).getCenter().y), 2));
int index = 0;
for ( int i = 1; i < itemList.size(); i++ ) {
if ( i % 2 == 0 ) {
double temp = Math.sqrt(Math.pow((center.x - itemList.get(i).getCenter().x), 2) +
Math.pow((center.y - itemList.get(i).getCenter().y), 2));
if ( temp <= distance ) {
distance = temp;
index = i;
}
}
}
return itemList.get(index);
}

找到这个”缝“之后,保存这个”缝“的下标,刷新适配器,在”缝“这个下标处显示那个用于提示的空格子。

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
ShowItem showItem = list.get(position);
if ( showItem != null )
if ( showItem.getType() == 0 ) {
//正文内容

} else {
//currSelectIndex是缝的下标
if ( currSelectIndex == position ) {
(( MyHolderDivider ) holder).tv_divider.setVisibility(View.VISIBLE);
} else {
(( MyHolderDivider ) holder).tv_divider.setVisibility(View.GONE);
}
}
}

释放”单词块“的时候

在释放”单词块“的时候,我们需要判断当前是否还在范围内,如果是在范围内,就在”缝“的地方插入”单词块“内部的单词值,然后隐藏掉”单词块“,否则,隐藏刚刚用于提示的空格子并将”单词块“移动到之前的位置。

//抬起手指的一瞬间
if ( event.getAction() == MotionEvent.ACTION_UP ) {
//如果在RecyclerView的范围内才处理 否则回退到原地
if ( isInArea ) {
//添加成功 移除之前的视图
v.setVisibility(View.GONE);
//检查并设置结果 最好提取出来
ShowItem result = new ShowItem((( TextView ) v).getText().toString(), 0);
if ( rightIndex == currSelectIndex ) {
//正确
result.setIsRight(1);
} else {
//错误
result.setIsRight(2);
}
list.add(currSelectIndex + 1, result);
list.add(currSelectIndex + 2, new ShowItem("", 1));
} else {
//未成功添加抬起的时候回归原地
v.setX(firstX);
v.setY(firstY);
}
//重置位置

currSelectIndex = -1;
flowAdapter.notifyDataSetChanged();
}

下面整个是多类型的适配器的代码,由于比较简单就写的比较随意,没有多去封装啥的:

class FlowAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private List list;

public FlowAdapter(List list) {
this.list = list;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if ( viewType == 0 ) {
//正文内容类型
return new MyHolder(View.inflate(MainActivity.this, R.layout.flow_item, null));
} else {
//占位符类型
return new MyHolderDivider(View.inflate(MainActivity.this, R.layout.flow_divider, null));
}
}

@Override
public int getItemViewType(int position) {
return list.get(position).getType();
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
ShowItem showItem = list.get(position);
if ( showItem != null )
if ( showItem.getType() == 0 ) {
//正文内容
TextView textView = (( MyHolder ) holder).text;
textView.setText(list.get(position).des);
} else {
//是否显示空格子
if ( currSelectIndex == position ) {
(( MyHolderDivider ) holder).tv_divider.setVisibility(View.VISIBLE);
} else {
(( MyHolderDivider ) holder).tv_divider.setVisibility(View.GONE);
}
}
}

@Override
public int getItemCount() {
return list.size();
}

class MyHolder extends RecyclerView.ViewHolder {

private TextView text;

public MyHolder(View itemView) {
super(itemView);
text = ( TextView ) itemView.findViewById(R.id.flow_text);
}
}

class MyHolderDivider extends RecyclerView.ViewHolder {

private TextView tv_divider;

public MyHolderDivider(View itemView) {
super(itemView);
tv_divider = ( TextView ) itemView.findViewById(R.id.tv_divider);
}
}
}

最后就是处理用户答案和正确答案的拼接与显示工作已经对用户的答案进行评判的过程,像什么答案正确显示绿色,错误显示红色,比较简单,就不再赘述,为了减少篇幅,就不再贴出整个代码了,感兴趣的可以查看源码,我会将源码放到Github上,如果感觉有用,欢迎star,哈哈。

注:由于时间比较赶,所以有些地方的代码和命名不是很规范,敬请谅解。

项目地址和结语

Github地址: DragDemo
错误显示红色,比较简单,就不再赘述,为了减少篇幅,就不再贴出整个代码了,感兴趣的可以查看源码,我会将源码放到Github上,如果感觉有用,欢迎star,哈哈。

注:由于时间比较赶,所以有些地方的代码和命名不是很规范,敬请谅解。

项目地址和结语

Github地址: DragDemo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用 Kotlin 编写第三方安卓开发客服功能,您可以按照以下步骤进行: 1. 集成第三方 SDK:您可以选择一个第三方客服 SDK,将其添加到您的项目中。例如,融云的 SDK 可以在 Gradle 中添加以下依赖: ```groovy implementation 'io.rong:imlib-kotlin:4.0.0' ``` 2. 初始化 SDK:在应用程序启动时,您应该初始化客服 SDK。例如,融云的 SDK 可以在 Application 类中初始化: ```kotlin class MyApplication : Application() { override fun onCreate() { super.onCreate() RongIM.init(this) } } ``` 3. 登录客服账号:客服 SDK 需要您提供客服账号信息。您可以在应用程序中提供一个登录界面,让用户输入客服账号和密码。例如,以下代码展示了如何使用融云 SDK 登录客服账号: ```kotlin RongIM.connect(token, object : RongIMClient.ConnectCallback() { override fun onSuccess(userId: String?) { // 登录成功 } override fun onError(errorCode: RongIMClient.ErrorCode?) { // 登录失败 } override fun onTokenIncorrect() { // token 失效 } }) ``` 4. 实现客服聊天界面:您可以使用 RecyclerView 和 Adapter 等组件来创建客服聊天界面。例如,以下代码展示了如何使用 RecyclerView 显示聊天消息: ```kotlin val adapter = ChatAdapter() recyclerView.adapter = adapter RongIMClient.setOnReceiveMessageListener { message, left -> if (left) { // 收到离线消息 } else { // 收到在线消息 adapter.addMessage(message) recyclerView.smoothScrollToPosition(adapter.itemCount - 1) } true } ``` 5. 发送消息:当用户在客服聊天界面中输入消息后,您需要使用客服 SDK 发送消息。例如,以下代码展示了如何使用融云 SDK 发送文本消息: ```kotlin val content = TextMessage.obtain(text) val message = Message.obtain(targetId, conversationType, content) RongIM.getInstance().sendMessage(message, null, null, object : RongIMClient.SendMessageCallback() { override fun onSuccess(message: Message?) { // 发送成功 } override fun onError(message: Message?, errorCode: RongIMClient.ErrorCode?) { // 发送失败 } }) ``` 以上是使用 Kotlin 编写第三方安卓开发客服功能的基本步骤。具体实现可能会有所差异,您需要根据您选择的客服 SDK 进行相应的调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值