实现Android中@标签用户功能

在Instagram等社交媒体应用中,经常看到用户通过@符号来标记其他用户,这是一个非常实用的功能。本文将介绍如何在Android应用中实现类似的功能,包括用户输入时的筛选和点击标签跳转到用户资料页面的实现方法。

在本文中,不会深入讨论后端Web服务的细节,而是专注于Android端的实现。目标是在用户输入@符号时调用用户列表,然后根据用户输入的字符继续筛选用户列表。此外,希望在用户点击标签时能够链接到标记的用户名,并显示用户的个人资料页面。

使用代码

首先,需要一个EditText控件供用户输入文本。更喜欢使用RelativeLayout。在EditText控件下方,有一个ListView控件,其可见性设置为"gone",宽度和高度设置为"match_parent"。这是关键,因为当找到一个用户标签时,ListView将变为可见,并填满屏幕,允许用户选择要标记的用户。

<EditText android:id="@+id/myEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textMultiLine" android:minLines="5" android:maxLines="5" /> <ListView android:id="@+id/myUsers" android:layout_width="match_parent" android:layout_height="match_parent" android:divider="#E6E6E6" android:dividerHeight="2dip" android:paddingLeft="20dip" android:paddingRight="20dip" android:visibility="gone" android:background="#ffffff" />

接下来,为EditText控件添加TextWatcher。在TextWatcher类中,当用户在EditText控件中输入时,afterTextChanged方法将被触发,并向Editable参数传递来自EditText控件的值。使用正则表达式来查找跟随@字符的小写和大写字母数字字符串,包括-和.字符。不允许空格或其他特殊字符。重要的是仅在从光标当前位置开始的匹配上执行。这将允许在EditText控件中输入多个标签。一旦找到了当前的标签,那就是想要获取的子字符串,不包括@,并将其作为参数传递给后端服务,后端服务将返回用户列表。这也是想要将ListView的可见性设置为VISIBLE的地方。在RelativeLayout中,将ListView放置在底部,并将match_parent作为宽度和高度值,将使其覆盖布局中的所有其他控件。

this.mEditText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable editable) { String text = editable.toString(); Pattern p = Pattern.compile("[@][a-zA-Z0-9-.]+"); Matcher m = p.matcher(text); int cursorPosition = mEditText.getSelectionStart(); while (m.find()) { if (cursorPosition >= m.start() && cursorPosition <= m.end()) { final int s = m.start() + 1; final int e = m.end(); // add 1 to ommit the "@" tag loadUsersFromBackEnd(text.substring(s, e)); break; } } } });

当查看其他用户的帖子或评论时,希望找到标签并使其在TextView中可点击。再次使用Pattern和Matcher类来找到标签。ClickableSpan类用于使文本的子串可点击。当找到用户标签的模式匹配时,创建ClickableSpan类的实例,覆盖onClick方法。在这个例子中,创建了一个Intent,将用户的友好名称(不包括@字符)传递给用户资料活动。同样,不会覆盖Intent和在活动之间传递值。这段代码片段很可能会在一个Adapter类中,该类将数据记录绑定到ListView。当用户滚动ListView内容时,用户标签将像超链接一样出现。点击它们将执行ClickableSpan的onClick方法。

Pattern p = Pattern.compile("[@][a-zA-Z0-9-.]+"); Matcher m = p.matcher(ss); while (m.find()) { final int s = m.start() + 1; // add 1 to omit the "@" tag final int e = m.end(); ClickableSpan clickableSpan = new ClickableSpan() { @Override public void onClick(View textView) { Intent intent = new Intent(mContext, com.myawesomeapp.UserActivity.class); intent.putExtra(UserActivity.EXTRA_FRIENDLY_NAME, wallPost.getMessage().substring(s, e)); mContext.startActivity(intent); } }; ss.setSpan(clickableSpan, m.start(), m.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485