[Android]TextUtils.ellipsize()截取指定长度字符串(附图文混排)

本文介绍了如何使用Android的TextUtils.ellipsize()方法来截取指定长度的字符串,同时提供了图文混排的示例,帮助开发者实现字符串显示的优化处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:http://zilla.blog.51cto.com/3095640/984775

效果图:


实现代码:

		
		// 监听布局变化,直接获取显示的长度
		txtDescription.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
			
			@Override
			public void onGlobalLayout() {
				if(availableTextWidth == 0&&txtDescription.getWidth()>0){
					TextPaint paint  = txtDescription.getPaint();
					
					int paddingLeft = txtDescription.getPaddingLeft();
					int paddingRight= txtDescription.getPaddingRight();
					
					int bufferWidth =(int) paint.getTextSize()*3;//缓冲区长度,空出两个字符的长度来给最后的省略号及图片
					// 计算出2行文字所能显示的长度
					availableTextWidth = (txtDescription.getWidth() - paddingLeft - paddingRight) * LINE_COUNT- bufferWidth;
					// 根据长度截取出剪裁后的文字
					String ellipsizeStr = (String) TextUtils.ellipsize(DESCRIPTION, (TextPaint) paint, availableTextWidth, TextUtils.Trunca
<think>我们有一个条件判断逻辑,用于根据psn和barcode的值设置TextView的本,如果两者都为空则隐藏TextView。 代码逻辑如下: 1. 如果psn非空,设置本为"PSN:" + psn 2. 否则,如果barcode非空,设置本为"Barcode:" + barcode 3. 如果psn和barcode都为空,则隐藏TextView(View.GONE) 但是,我们可以注意到,在第一个条件中,当psn非空时,我们设置了本并且TextView会显示(因为代码中没有设置可见性为可见,但默认是可见的,除非之前被隐藏过)。 同样,当psn为空但barcode非空时,我们设置本并会显示。 当两者都为空时,我们隐藏TextView。 然而,这段代码有一个潜在的问题:如果之前设置了TextView的可见性为GONE,而在某些情况下(比如psn或barcode有值)我们并没有显式地将它设置为可见(VISIBLE),那么即使我们设置了本,它也可能是不可见的。 因此,改进的代码应该在设置本的同时,确保TextView是可见的(除非在两者都为空时隐藏)。 修改后的代码逻辑: 1. 如果psn非空:设置本为"PSN:" + psn,并设置TextView为可见。 2. 否则,如果barcode非空:设置本为"Barcode:" + barcode,并设置TextView为可见。 3. 否则(两者都为空):隐藏TextView。 这样,无论之前的状态如何,我们都能正确控制其可见性。 以下是改进后的代码:</think>### 回答:Android 本视图条件显示优化 这段代码用于根据设备序列号(PSN)和条形码(barcode)的值动态设置本视图的显示内容。我将提供优化后的完整实现方案,并解释其工作原理。 #### 原始代码分析 ```java if(!TextUtils.isEmpty(psn)){ mBarCodeTitleTv.setText("PSN:" + psn); }else if(!TextUtils.isEmpty(barcode)){ mBarCodeTitleTv.setText("Barcode:" + barcode); } if(TextUtils.isEmpty(psn) && TextUtils.isEmpty(barcode)){ mBarCodeTitleTv.setVisibility(View.GONE); } ``` 这段代码存在几个可优化的地方: 1. 没有处理视图的可见性重置(当有值时需要显示) 2. 字符串拼接直接在代码中,不利于国际化 3. 逻辑可以更简洁高效 4. 缺少空值安全处理 #### 优化后的完整实现 ```java import android.view.View; import android.widget.TextView; import androidx.annotation.Nullable; public class DeviceInfoDisplay { private final TextView mBarCodeTitleTv; private static final String PSN_PREFIX = "PSN: "; private static final String BARCODE_PREFIX = "Barcode: "; public DeviceInfoDisplay(TextView barCodeTitleTv) { this.mBarCodeTitleTv = barCodeTitleTv; } /** * 更新设备信息显示 * @param psn 设备序列号 * @param barcode 设备条形码 */ public void updateDeviceInfo(@Nullable String psn, @Nullable String barcode) { // 优先显示PSN,其次显示barcode if (!TextUtils.isEmpty(psn)) { setDeviceInfoVisible(true); mBarCodeTitleTv.setText(PSN_PREFIX + psn); } else if (!TextUtils.isEmpty(barcode)) { setDeviceInfoVisible(true); mBarCodeTitleTv.setText(BARCODE_PREFIX + barcode); } else { // 两者都为空时隐藏视图 setDeviceInfoVisible(false); } } /** * 设置设备信息视图的可见性 * @param visible 是否可见 */ private void setDeviceInfoVisible(boolean visible) { mBarCodeTitleTv.setVisibility(visible ? View.VISIBLE : View.GONE); } /** * 安全获取设备信息显示本 */ public String getDisplayText() { return mBarCodeTitleTv.getVisibility() == View.VISIBLE ? mBarCodeTitleTv.getText().toString() : ""; } } ``` #### 使用示例 ```java // 在Activity或Fragment中使用 public class DeviceInfoActivity extends AppCompatActivity { private DeviceInfoDisplay deviceInfoDisplay; private TextView mBarCodeTitleTv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_device_info); mBarCodeTitleTv = findViewById(R.id.barCodeTitleTv); deviceInfoDisplay = new DeviceInfoDisplay(mBarCodeTitleTv); // 获取设备信息 String psn = getDevicePsn(); // 实现获取PSN的方法 String barcode = getDeviceBarcode(); // 实现获取barcode的方法 // 更新UI显示 updateDeviceInfoDisplay(psn, barcode); } private void updateDeviceInfoDisplay(String psn, String barcode) { deviceInfoDisplay.updateDeviceInfo(psn, barcode); // 可选:添加动画效果 if (mBarCodeTitleTv.getVisibility() == View.VISIBLE) { animateViewAppearance(mBarCodeTitleTv); } } private void animateViewAppearance(View view) { view.setAlpha(0f); view.animate() .alpha(1f) .setDuration(300) .setInterpolator(new AccelerateDecelerateInterpolator()) .start(); } } ``` ### 代码解析与优化点 #### 1. 封装视图控制逻辑 ```java public void updateDeviceInfo(@Nullable String psn, @Nullable String barcode) { if (!TextUtils.isEmpty(psn)) { setDeviceInfoVisible(true); mBarCodeTitleTv.setText(PSN_PREFIX + psn); } else if (!TextUtils.isEmpty(barcode)) { setDeviceInfoVisible(true); mBarCodeTitleTv.setText(BARCODE_PREFIX + barcode); } else { setDeviceInfoVisible(false); } } ``` - **优化点**:显式设置视图可见性,确保在显示内容时视图是可见的 - **空安全**:使用`@Nullable`注解和`TextUtils.isEmpty()`检查 - **单一职责**:每个条件分支都处理视图状态和内容设置 #### 2. 字符串资源优化 ```java private static final String PSN_PREFIX = "PSN: "; private static final String BARCODE_PREFIX = "Barcode: "; ``` - **最佳实践**:将字符串前缀定义为常量,便于维护和国际化 - **扩展性**:可轻松替换为资源字符串: ```java // 在strings.xml中定义 <string name="psn_prefix">PSN: </string> <string name="barcode_prefix">Barcode: </string> // 代码中使用 private final String psnPrefix = getString(R.string.psn_prefix); ``` #### 3. 可见性管理封装 ```java private void setDeviceInfoVisible(boolean visible) { mBarCodeTitleTv.setVisibility(visible ? View.VISIBLE : View.GONE); } ``` - **清晰性**:使用布尔参数简化可见性设置 - **一致性**:确保所有分支都正确处理可见性 - **扩展点**:可在此方法中添加动画或额外逻辑 #### 4. 增强功能方法 ```java public String getDisplayText() { return mBarCodeTitleTv.getVisibility() == View.VISIBLE ? mBarCodeTitleTv.getText().toString() : ""; } ``` - **实用功能**:提供获取当前显示本的方法 - **空安全**:返回空字符串而非null,避免空指针异常 - **状态感知**:只在视图可见时返回有效本 ### 高级优化:响应式实现 使用LiveData和ViewModel实现响应式更新: ```java // DeviceInfoViewModel.java import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; public class DeviceInfoViewModel extends ViewModel { private final MutableLiveData<String> psnLiveData = new MutableLiveData<>(); private final MutableLiveData<String> barcodeLiveData = new MutableLiveData<>(); public void setPsn(String psn) { psnLiveData.setValue(psn); } public void setBarcode(String barcode) { barcodeLiveData.setValue(barcode); } public LiveData<DeviceDisplayInfo> getDisplayInfo() { return Transformations.map(new MediatorLiveData<Pair<String, String>>() { { addSource(psnLiveData, psn -> setValue(Pair.create(psn, barcodeLiveData.getValue()))); addSource(barcodeLiveData, barcode -> setValue(Pair.create(psnLiveData.getValue(), barcode))); } }, pair -> { String psn = pair.first; String barcode = pair.second; if (!TextUtils.isEmpty(psn)) { return new DeviceDisplayInfo(true, "PSN: " + psn); } else if (!TextUtils.isEmpty(barcode)) { return new DeviceDisplayInfo(true, "Barcode: " + barcode); } else { return new DeviceDisplayInfo(false, ""); } }); } public static class DeviceDisplayInfo { public final boolean visible; public final String text; public DeviceDisplayInfo(boolean visible, String text) { this.visible = visible; this.text = text; } } } // 在Activity中使用 DeviceInfoViewModel viewModel = new ViewModelProvider(this).get(DeviceInfoViewModel.class); viewModel.getDisplayInfo().observe(this, info -> { mBarCodeTitleTv.setVisibility(info.visible ? View.VISIBLE : View.GONE); mBarCodeTitleTv.setText(info.text); }); // 更新数据 viewModel.setPsn(getDevicePsn()); viewModel.setBarcode(getDeviceBarcode()); ``` ### 最佳实践总结 1. **空值处理**: ```java // 使用TextUtils.isEmpty()而不是null检查 if (!TextUtils.isEmpty(value)) { ... } ``` 2. **视图状态管理**: ```java // 设置可见性时同时处理显示和隐藏 view.setVisibility(shouldShow ? View.VISIBLE : View.GONE); ``` 3. **字符串处理**: ```java // 使用String.format进行本地化 String displayText = getString(R.string.psn_format, psn); ``` 4. **性能优化**: ```java // 避免不必要的视图更新 if (!currentText.equals(newText)) { textView.setText(newText); } ``` 5. **错误处理**: ```java // 添加默认值处理 String safePsn = !TextUtils.isEmpty(psn) ? psn : "N/A"; ``` 这个优化方案提供了更健壮、可维护的设备信息显示逻辑,正确处理了各种边界情况,并提供了扩展点以适应更复杂的需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值