今天做一个消息显示的界面,由于之前没有使用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啊,如果您知道原因的话,请多多交流,在博客下留言,我会及时回复!