2016-12-23 7 views
2

私はListViewを持っており、それにフッターを追加しました。私はフッタをプログラムに含めてListView全体の高さを取得しようとしています。その目的のために私は以下のコードを書きました。リストビュー内のフッターの高さを計算する方法

私が今問題を抱えているのは、APIレベルが18より大きいデバイスでコード を実行するとコードが正常に動作することです。しかし、デバイスのAPIレベルが18以下の場合、アプリケーションがクラッシュし、私は下記のlogcatエラーが表示されます。

調査とデバッグの後、APIレベルが18以下のデバイスで作業すると、コードセクションの "calcLisVieHeight"のfor-loopsが最後に達したときに何か問題が発生することがわかりましたフッターであるリスト内の項目。

したがって、私は同じコードを2つの部分に分割することに決めました。最初の部分には、フッタを除いてリスト内のアイテム全体をループするforループが含まれています。フッターの高さを計算するコードを追加しました。 フッターの高さはどれくらい大きいのでしょうか?そのコードは次のとおりです。

int desiredWidth = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 
     int desiredHeight = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 

     for (int i = 0; i < listView.getCount() - 1; i++) { 
      View childView = listView.getAdapter().getView(i, null, listView); 

      if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { 
       childView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); 
      } 

      childView.measure(desiredWidth, desiredHeight); 
      height += childView.getMeasuredHeight(); 
      Log.v(TAG, "height: " + height); 
     } 

     ////////////////////calc footer height//////////////////////// 
     View childView = listView.getAdapter().getView(listView.getCount() - 1, null, listView); 
     int heightFooter = 0; 

     if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2) { 
      childView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); 
     } 

     childView.measure(desiredWidth, desiredHeight); 
     height += childView.getMeasuredHeight(); 
     heightFooter = childView.getMeasuredHeight(); 
     Log.v(TAG, "height: " + height); 
     Log.v(TAG, "heightFooter: " + heightFooter); 

     //dividers height 
     height += listView.getDividerHeight() * listView.getCount() + childView.getHeight(); 

私はアプリケーションが正常に動作しますが、それは私がそのclaculatesコードを活性化させる場合は、以下のlogcatメッセージを生成するクラッシュフッターの高さを計算するための責任のコードなしで上記のコードを実行したとき

:フッター

の高さは、私がなぜフッターの高さが計算されるカントか、正しく

calcLisVieHeightそれを計算する方法を教えてください

switch (viewId) { 
     case R.id.versicherungsListeActivity2mod_lisVie_versDetails: 

      heightInPix = this.mLayoutDimsCtrl.calcLisVieHeight(listView); 

      if (heightInPix != -1) { 
       RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, heightInPix); 
       param.addRule(RelativeLayout.BELOW, ruleSubject); 
       container.setLayoutParams(param); 
       listView.requestLayout(); 
      } 
      break; 
      ... 
      ... 
      ... 


public int calcLisVieHeight(final ListView listView) { 
...... 
...... 
int desiredWidth = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 
int desiredHeight = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 

     for (int i = 0; i < listView.getCount(); i++) { 
      View childView = listView.getAdapter().getView(i, null, listView); 

      if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { 
       childView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); 
      } 

      childView.measure(desiredWidth, desiredHeight); 
      height += childView.getMeasuredHeight(); 
      Log.v(TAG, "height: " + height); 
     } 

     //dividers height 
     height += listView.getDividerHeight() * listView.getCount() + childView.getHeight(); 
     ...... 
     ...... 
     } 

logcat

java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams 
     at android.widget.ListView.setupChild(ListView.java:1888) 
     at android.widget.ListView.makeAndAddView(ListView.java:1857) 
     at android.widget.ListView.fillDown(ListView.java:682) 
     at android.widget.ListView.fillFromTop(ListView.java:748) 
     at android.widget.ListView.layoutChildren(ListView.java:1653) 
     at android.widget.AbsListView.onLayout(AbsListView.java:2447) 
     at android.view.View.layout(View.java:15204) 
     at android.view.ViewGroup.layout(ViewGroup.java:4793) 
     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677) 
     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531) 
     at android.widget.LinearLayout.onLayout(LinearLayout.java:1440) 
     at android.view.View.layout(View.java:15204) 
     at android.view.ViewGroup.layout(ViewGroup.java:4793) 
     at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1076) 
     at android.view.View.layout(View.java:15204) 
     at android.view.ViewGroup.layout(ViewGroup.java:4793) 
     at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 
     at android.widget.ScrollView.onLayout(ScrollView.java:2144) 
     at android.view.View.layout(View.java:15204) 
     at android.view.ViewGroup.layout(ViewGroup.java:4793) 
     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677) 
     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531) 
     at android.widget.LinearLayout.onLayout(LinearLayout.java:1440) 
     at android.view.View.layout(View.java:15204) 
     at android.view.ViewGroup.layout(ViewGroup.java:4793) 
     at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 
     at android.view.View.layout(View.java:15204) 
     at android.view.ViewGroup.layout(ViewGroup.java:4793) 
     at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:349) 
     at android.view.View.layout(View.java:15204) 
     at android.view.ViewGroup.layout(ViewGroup.java:4793) 
     at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 
     at android.view.View.layout(View.java:15204) 
     at android.view.ViewGroup.layout(ViewGroup.java:4793) 
     at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2260) 
     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2007) 
     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1249) 
     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6364) 
     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791) 
     at android.view.Choreographer.doCallbacks(Choreographer.java:591) 
     at android.view.Choreographer.doFrame(Choreographer.java:561) 
     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777) 
     at android.os.Handler.handleCallback(Handler.java:730) 
     at android.os.Handler.dispatchMessage(Handler.java:92) 
     at android.os.Looper.loop(Looper.java:176) 
     at android.app.ActivityThread.main(ActivityThread.java:5419) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:525) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862) 
     at dalvik.system.NativeStart.main(Native Method) 
+0

私はあなたのコードの別のスニペットから私は全体の画像が表示されないので、確かに今のところクラッシュRelativeLayout.LayoutParams'に 'AbsListView.LayoutParams'があると設定されているので、まずRelativeLayout.LayoutParamsをAbsListView.LayoutParamsに変更してから、あなたに他の問題があるかどうかを見てみましょう。 – Vilen

+0

@Vilenしかし、API> 18で同じコードを実行すると、RelativeLayout.LayoutParamsをAbsListView.LayoutParamsに変更せずにフィンが動作します。 – user2121

+0

@Vilen次に、私があなたの提案した答えを試した後、java.lang.ClassCastException:androidを受け取ります。 widget.AbsListView $ LayoutParamsはandroid.widget.RelativeLayout $ LayoutParamsにキャストすることはできません。 – user2121

答えて

0

あなたが望むものを達成するためにあなたのCustomListViewとして、このクラスを使用します。それがあなたのために働くことを願っています。

import android.content.Context; 
import android.util.AttributeSet; 
import android.widget.ListView; 

public class MyListView extends ListView { 
public MyListView(Context context) { 
    super(context); 
} 

public MyListView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

public MyListView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    int heightSpec; 

    if (getLayoutParams().height == LayoutParams.WRAP_CONTENT) { 
     // The great Android "hackatlon", the love, the magic. 
     // The two leftmost bits in the height measure spec have 
     // a special meaning, hence we can't use them to describe height. 
     heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); 
    } else { 
     // Any other height should be respected as is. 
     heightSpec = heightMeasureSpec; 
    } 

    super.onMeasure(widthMeasureSpec, heightSpec); 
} 
} 

`

+0

しかし、私のリストアダプターはBaseAdapterを拡張し、私は上書きできません。 – user2121

+0

できます。 ......それはアダプタです........リストビューを簡単にカスタマイズすることができます.... スクロールビューの下にListViewを配置したいですか? – Ashish

+0

私のリストビューは既にスクロールビューを隠しています。しかし、私はオーバーレイonMeasureを受け取りません。 – user2121

0

たぶん私は間違っているんだけど、私見、あなたのコードを読んで、次の操作を行う必要があります:(

for loop内部で、アプリであなたはfooterにアクセスする必要がどこにリストの最後の項目なのでindex = length -1api lvlのチェックを行います。そう

if(currentIndex == footerIndex && currentApiLVL <= 18) //obv replace with the correct code, I don't have a compiler atm 
{ 
    myFooterView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.WRAP_CONTENT, AbsListView.LayoutParams.WRAP_CONTENT)); 
} else { 

    myFooterView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); 
} 

バージョンが< = 18であれば項目はフッター(最後の項目)ともであれば、あなたは最初をチェックする必要があります。その場合、とその場合にのみ(どちらの条件でも)AbsListViewとしてparamsを設定し、RelativeLayoutとして設定する必要はありません。

多分、私はこれがあなたを助けることを望みます。私のコードを試してみてください:

関連する問題