开发问题及解决 java.lang.ClassCastException:android.widget.LinearLayout$LayoutParams

本文探讨了在Android中使用代码动态调整布局高度时遇到的ClassCastException问题,并通过实例演示如何正确设置LayoutParams来避免运行时错误。

Caused by: java.lang.ClassCastException:android.widget.LinearLayout$LayoutParams

最近,在android中用代码动态改变某种布局(组件)的高度时,会遇到如题所示的类转换异常。上网查了一下,如下所示:

These supply parameters to theparentof this view specifying how it should be arranged. There are many subclasses of ViewGroup.LayoutParams, and these correspond to the different subclasses of ViewGroup that are responsible for arranging their children.

So basically, if you are adding a view to another, you MUST set the LayoutParams of the view to the LayoutParams type that the parent uses, or you will get a runtime error.

我是这样理解的,如果你要将一个view添加到另一个布局中,你必须设定该View的布局参数为其父类所使用的布局参数类型。即要在代码中动态改变某组件的高度,其布局参数类型应该是其父类所使用的布局参数类型。
 比如:


<LinearLayout

  xmlns:android="http://schemas.android.com/apk/res/android"  

  android:layout_width="wrap_content"

  android:layout_height="wrap_content">  

  

<FrameLayout 

android:id="@+id/FrameLayout01" 

android:layout_width="wrap_content" 

android:layout_height="wrap_content" /> 

</LinearLayout>

若想在代码中动态改变FrameLayout的大小,应该这样写:


FrameLayout frameLayout=(FrameLayout) convertView.findViewById(R.id.FrameLayout01);  

 LinearLayout.LayoutParams ff=new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, height); 
frameLayout.setLayoutParams(ff);
注:其布局参数类型应该线性布局LinearLayout.LayoutParams的类型,而不是帧布局FrameLayout.LayoutParams。

package com.example.layoutdome; import androidx.appcompat.app.AppCompatActivity; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.util.TypedValue; import android.view.View; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.MediaController; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import android.widget.VideoView; import com.example.mylibrary.Usages; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class MainActivity extends AppCompatActivity implements DataUploader.OnDataReceivedListener { private List<DataList> dataLists = new ArrayList<>(); private int type; private DataList.DataDTO.ComponentsDTO.SetStyleDTO setStyle; private TextView tvDate, tvWeather, tvList; private FullScreenVideoView tvVideo; private VerticalMarqueeTextView tvMarquee; private String fileUrl; private List<DataList.DataDTO.ComponentsDTO.SetStyleDTO.VideoListDTO> videoList; private int currentIndex = 0; // 用于追踪当前播放的视频索引 private MediaController mMediaController; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView = (TextView) findViewById(R.id.text); tvMarquee = (VerticalMarqueeTextView) findViewById(R.id.tv_marquee); tvVideo = (FullScreenVideoView) findViewById(R.id.tv_video); tvDate = (TextView) findViewById(R.id.tv_date); tvWeather = (TextView) findViewById(R.id.tv_weather); tvList = (TextView) findViewById(R.id.tv_list); textView.setText("版本号:" + APKVersionCodeUtils.getVersionCode(MainActivity.this)); Usages usages = new Usages(); usages.getTimes(MainActivity.this); new DataUploader("ES0001", this).execute(); } @Override public void onDataReceived(DataList dataList) { // 当数据接收到时更新 dataLists dataLists.clear(); dataLists.add(dataList); // 输出数据 for (int i = 0; i < dataLists.size(); i++) { DataList.DataDTO data = dataLists.get(i).getData(); List<DataList.DataDTO.ComponentsDTO> components = data.getComponents(); for (int j = 0; j < components.size(); j++) { type = components.get(j).getType(); Log.i("components:", "" + type); setStyle = components.get(j).getSetStyle(); //1文本组件 2图片组件 3视频组件 4天气 5日期 6线路 if (type == 1) { int height = setStyle.getHeight(); int width = setStyle.getWidth(); int left = setStyle.getLeft(); int top = setStyle.getTop(); String noticeText = setStyle.getNoticeText(); tvMarquee.setTextList(Arrays.asList( noticeText )); tvMarquee.startMarquee(); Log.i("aaaaaaa", "文本组件marqueeTop:" + top); Utils.updateLayoutParams(MainActivity.this,tvMarquee,width,height,left,top); Log.i("aaaaaaa", "文本组件:" + type); } else if (type == 2) { // int height = setStyle.getHeight(); // int width = setStyle.getWidth(); // int left = setStyle.getLeft(); // int top = setStyle.getTop(); // int videoWidth = Integer.parseInt(String.valueOf(width)); // int videoHeight = Integer.parseInt(String.valueOf(height)); // int videoTop = Integer.parseInt(String.valueOf(top)); // FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(videoWidth, videoHeight); params.width = dip2px(MainActivity.this, videoWidth); // params.height = dip2px(MainActivity.this, videoHeight); // params.leftMargin = dip2px(MainActivity.this, left); // params.topMargin = dip2px(MainActivity.this, videoTop); // tvVideo.setLayoutParams(params); // 重新设置 LayoutParams } else if (type == 3) { int height = setStyle.getHeight(); int width = setStyle.getWidth(); int left = setStyle.getLeft(); int top = setStyle.getTop(); Utils.updateLayoutParams(MainActivity.this,tvVideo,width,height,left,top); videoList = setStyle.getVideoList(); // 开始播放第一个视频 playNextVideo(); Log.i("aaaaaaa", "视频组件:" + type); } else if (type == 4) { int height = setStyle.getHeight(); int width = setStyle.getWidth(); int left = setStyle.getLeft(); int top = setStyle.getTop(); Utils.updateLayoutParams(MainActivity.this,tvWeather,width,height,left,top); Log.i("aaaaaaa", "天气组件:" + type); // Log.i("aaaaaaa", "天气组件左边距:" + params.leftMargin); // Log.i("aaaaaaa", "天气组件高:" + params.height); // Log.i("aaaaaaa", "天气组件宽:" + params.width ); // Log.i("aaaaaaa", "天气组件距上边距:" + params.topMargin); } else if (type == 5) { int height = setStyle.getHeight(); int width = setStyle.getWidth(); int left = setStyle.getLeft(); int top = setStyle.getTop(); Utils.updateLayoutParams(MainActivity.this,tvDate,width,height,left,top); Log.i("aaaaaaa", "日期组件:" + type); } else if (type == 6) { int height = setStyle.getHeight(); int width = setStyle.getWidth(); int left = setStyle.getLeft(); int top = setStyle.getTop(); Utils.updateLayoutParams(MainActivity.this,tvList,width,height,left,top); Log.i("aaaaaaa", "线路组件:" + type); } } } } private void playNextVideo() { mMediaController = new MediaController(this); if (currentIndex < videoList.size()) { String fileUrl = videoList.get(currentIndex).getStaticFileName(); Log.i("aaaaaaa", "视频地址:" + fileUrl); Uri parse = Uri.parse("http://117.71.111.12:8087/eb/static/"+fileUrl); tvVideo.setVideoURI(parse); mMediaController.setVisibility(View.GONE); mMediaController.setMediaPlayer(tvVideo); tvVideo.setMediaController(mMediaController); tvVideo.start(); // 设置视频准备好之后的监听 tvVideo.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { try { tvVideo.start(); } catch (Exception e) { Log.e("VideoPlayError", "播放视频时出错: " + e.getMessage()); } } }); // 设置视频播放完成后的监听 tvVideo.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { if (currentIndex < videoList.size() - 1) { currentIndex++; // Move to the next video playNextVideo(); // Play next video } else { Log.i("VideoPlayer", "所有视频均已播放"); } } }); } else { Log.i("aaaaaaa", "所有视频已播放完毕"); } // 检查文件格式和编码是否受支持 tvVideo.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { if (what == MediaPlayer.MEDIA_ERROR_UNSUPPORTED) { // 处理不支持的文件格式或编码 Log.e("VideoPlayer", "播放视频时发生错误. what: " + what + ", extra: " + extra); } return false; } }); } } package com.example.layoutdome; import android.content.Context; import android.view.View; import android.widget.FrameLayout; import android.widget.RelativeLayout; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.TimeZone; public class Utils { /** * 设置布局参数,改变控件位置 * @param view * @param width * @param height * @param left * @param top */ static void updateLayoutParams(Context context,View view, int width, int height, int left, int top) { FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, height); params.width = dip2px(context, width); params.height = dip2px(context, height); params.leftMargin = dip2px(context, left); params.topMargin = dip2px(context, top); view.setLayoutParams(params); // 重新设置 LayoutParams } /** * dp转为px * @param context 上下文 * @param dpValue dp值 * @return */ public static int dip2px(Context context, int dpValue) { float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } } 报错 java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
07-16
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值