2011-06-22 33 views
30

親として垂直方向のLinearLayoutがありますが、この親にプログラムで複数のビューを何度も追加したいと思います。今は、親に追加する前に、すべてのUI要素に新しい参照が追加されるたびに子供を膨らませています。これは非常に効率的ではないようですが、これを行うためのよりよい方法があります。同じビューを親に複数回追加する方法

私が使用しているコードは以下の通りです。forループの前に一度だけ膨張させた場合、実行時エラー "指定した子が既に親を持っています。

 LayoutInflater inflator = LayoutInflater.from(getBaseContext()); 
     LinearLayout parentPanel = findViewById(R.id.parent_pannel); 

     ArrayList<String> myList = getData(); 
     for(String data : myList) { 
      // inflate child 
      View item = inflator.inflate(R.layout.list_item, null); 
      // initialize review UI 
      TextView dataText = (TextView) item.findViewById(R.id.data); 
      // set data 
      dataText.setText(data); 
      // add child 
      parentPanel.addView(item); 
     } 
+0

私は同意すると、ビューを "複製"する簡単な方法があれば甘いだろうが、私はそれをまだ見つけていない。それ以上の膨らみがあります。しかし、あなたのコードスニペットから、あなたは 'ListView'を使いたいと思うと私は思うでしょう。 – dmon

+0

これは設計によるものです。 1つのビューに対して複数の親を持つことはできず、同じビューを複数回親に追加することもできません。 ViewGroups(と同様のシナリオ)のバグのないコードを作成するのは非常に難しいでしょう。 – inazaruk

+0

@dmon ListViewを使うレイアウトを設計しなかったのは、すべてのものをレイアウトしたいので、コードが複雑になるからです。私は効率のためにListViewにすべてを移動する必要がありますね。 – mkso

答えて

4

私はあなたのビューが何であるかはよく分からないが、あなたはXMLを膨張させる上で手動で作成している:あなたは明らかにSimple ListView & APIであなたのために行われている何かをしようと

ArrayList<String> myList = getData(); 
    for(String data : myList) { 

     LinearLayout layout = new LinearLayout(this); 
     layout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,    LayoutParams.WRAP_CONTENT)); 
     TextView textView = new TextView(this); 
     textView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); 

     textView.setText(data); 

     layout.addChild(textView);   

     parentPanel.addView(layout); 
    } 

をしかし、ええ

28

実際にインフレが遅いのを確認しましたか?私が知る限り、ビューを膨張させることは非常に高速です(ビューを手動で作成するのと同じくらい速い)。

あなたが聞こえるのは驚くかもしれませんが、実際には膨らませても、XMLはまったく解析されません。レイアウト用のXMLはコンパイル時に解析され、事前処理されます。これらはバイナリ形式で格納され、ビューのインフレーションを非常に効率的にします(実行時に生成されるXMLからビューを膨張させることができません)。

+1

興味深いty! – Blundell

+3

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/view/LayoutInflater.java 行424 – Teodor

+0

私は同意しませんXMLのインフレーションは常に最長の時間を必要とするため、レイアウト構造をできるだけ単純に保つようにしています。 –

4

複数回の注入は、同じ方法で1回のショットで行うことはできません。これはこれは動作します

LayoutInflater inflator = (LayoutInflater).getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    LinearLayout parentPanel = findViewById(R.id.parent_pannel); 

    ArrayList<String> myList = getData(); 
    for(String data : myList) { 
     // inflate child 
     View item = inflator.inflate(R.layout.list_item, null); 
     // initialize review UI 
     TextView dataText = (TextView) item.findViewById(R.id.data); 
     // set data 
     dataText.setText(data); 
     // add child 
     parentPanel.addView(item); 
    } 

作品を願って、少なくとも私に

+0

また、View v = inflater.inflate(R.layout.list_item、parent、false)を使って私のために働きました。その後、addView(v)を呼び出しています。 inflate(...)のように見えますが、すでにそこにある場合は接続しないように最適化しているかもしれません。 –

+0

上記のようにリサイクラビューの行内に動的に同じビューを追加する必要がある場合は、私に何か提案することができますか –

5

を働いていた、あなたはない、古いviewオブジェクトからnew viewを作成しようとする場合でも、オブジェクトは参照によって渡されることができます値ではないため、例外childAlreadyHasParentとしています。したがって、viewfor loopに入れて、それを膨らませる回数を入れてください。このループには、 beginniからプロセスを作成する膨張ラインだけでなく、

関連する問題