You must call removeView() on the child's parent first错误的解决方法

今天做一个消息显示的界面,由于之前没有使用ListView来显示,只是将每个消息的LayoutInflater成一个View 然后addView()上去,所以这次也想这么做,但是却出现了这个错误

The specified child already has a parent. You must call removeView() on the child's parent first

刚开始还搞不明白,下面是我出错前的代码:

public class PiccMsgActivity extends Activity implements OnClickListener{
	protected Button btPiccMsgBack;
	LinearLayout msg;
	View msg_picc;
	@Override
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_picc_msg);
		
		btPiccMsgBack = (Button) findViewById(R.id.btPiccMsgBack);
		btPiccMsgBack.setOnClickListener(this);
		msg = (LinearLayout)findViewById(R.id.PiccMsgList);
		
		for(int i=0;i<MainActivity.msg_list_picc.size();i++){
			if(msg_picc==null){
				msg_picc = getLayoutInflater().inflate(R.layout.picc_msg_item,null);
				TextView msg_type = (TextView)msg_picc.findViewById(R.id.msg_type);
				TextView msg_username = (TextView)msg_picc.findViewById(R.id.username_picc);
				TextView msg_content = (TextView)msg_picc.findViewById(R.id.msg_content);
				
				msg_type.setText(MainActivity.msg_list_picc.get(i).getMsgType());
				msg_username.setText(Picc_LoginInfo.userName+":");
				msg_content.setText(MainActivity.msg_list_picc.get(i).getMsgContent());
				ViewHold viewhold = new ViewHold();
				viewhold.setMsg_type(msg_type);
				viewhold.setMsg_username(msg_username);
				viewhold.setMsg_content(msg_content);
								
				msg_picc.setTag(viewhold);
				msg.addView(msg_picc);
			}else{
				ViewHold viewhold = (ViewHold)msg_picc.getTag();
				viewhold.getMsg_type().setText(MainActivity.msg_list_picc.get(i).getMsgType());
				viewhold.getMsg_username().setText(Picc_LoginInfo.userName+":");
				viewhold.getMsg_content().setText(MainActivity.msg_list_picc.get(i).getMsgContent());
				msg.addView(msg_picc);
			}
		}
	}
	@Override
	public void onClick(View v) {
		PiccMsgActivity.this.finish();
	}	
	class ViewHold{
		TextView msg_type;
		TextView msg_username;
		TextView msg_content;
		public TextView getMsg_type() {
			return msg_type;
		}
		public void setMsg_type(TextView msg_type) {
			this.msg_type = msg_type;
		}
		public TextView getMsg_username() {
			return msg_username;
		}
		public void setMsg_username(TextView msg_username) {
			this.msg_username = msg_username;
		}
		public TextView getMsg_content() {
			return msg_content;
		}
		public void setMsg_content(TextView msg_content) {
			this.msg_content = msg_content;
		}
		
	}
}


查看日志就在else执行体中的这个句话msg.addView(msg_picc); 出错了,我这个做法本来是想仿照ListView中 可以少执行下面这几行代码:

		msg_picc = getLayoutInflater().inflate(R.layout.picc_msg_item,null);
		TextView msg_type = (TextView)msg_picc.findViewById(R.id.msg_type);
		TextView msg_username = (TextView)msg_picc.findViewById(R.id.username_picc);
		TextView msg_content = (TextView)msg_picc.findViewById(R.id.msg_content);

因为膨胀出一个View是会花费较多的时间的,从而导致页面额跳转延时增加,影响用户的体验。我之前因为没有这样做,所以没有出错,但是这次这样做之后却报错了,在

ListView中这样做却不会出错,是什么原因呢?google这个错误,根本原因就是,一个孩子不能有两个父母,即同一个布局不能同时多次放置同一个View,,稍微改一下这段代码

就能顺利执行通过,改正的方法为:将for循环中的所有代码全都注释掉,只留下下面这段代码:

		View msg_picc = getLayoutInflater().inflate(R.layout.picc_msg_item,null);
		TextView msg_type = (TextView)msg_picc.findViewById(R.id.msg_type);
		TextView msg_username = (TextView)msg_picc.findViewById(R.id.username_picc);
		TextView msg_content = (TextView)msg_picc.findViewById(R.id.msg_content);
				
		msg_type.setText(MainActivity.msg_list_picc.get(i).getMsgType());
		msg_username.setText(Picc_LoginInfo.userName+":");
		msg_content.setText(MainActivity.msg_list_picc.get(i).getMsgContent());

即每次都膨胀出一个新的View,而不是在重复利用原来的View。这样改好了,但是我还是不明白为什么ListView中能够这样去用呢?为什么ListView中可以循环利用膨胀出来的

Item 但是ListView也是一个View啊,如果您知道原因的话,请多多交流,在博客下留言,我会及时回复!


 

 

你可能感兴趣的:(You must call removeView() on the child's parent first错误的解决方法)