Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7075763
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T06:12:59+00:00 2026-05-28T06:12:59+00:00

I’m trying to create a class that can be added to a Layout file,

  • 0

I’m trying to create a class that can be added to a Layout file, have an adapter set and then update from a DataSetObserver.

On the Nexus One this generally seems to work fine, however on the G1 I get some odd behaviour.

So the Layout File for the Activity is:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" android:layout_width="fill_parent"
 android:layout_height="fill_parent">

 <include android:layout_width="fill_parent"
  android:layout_height="wrap_content" android:id="@+id/ActionBarInclude"
  layout="@layout/action_bar"></include>

  <LinearLayout android:layout_width="fill_parent"
   android:layout_height="fill_parent" android:orientation="vertical"
   android:background="@drawable/action_bar_drop_shadow">

   <TextView android:layout_height="wrap_content"
    android:layout_width="fill_parent" android:gravity="center"
    android:id="@+id/AccountSummaryAppTitleTextView" android:text=""
    style="@style/titleTextView"></TextView>

   <co.uk.gauntface.android.admob.views.TabBarScrollView
    android:id="@+id/AccountSummaryTabBarScrollView"
    android:layout_width="fill_parent" android:layout_height="wrap_content"
    android:scrollbars="none">

   </co.uk.gauntface.android.admob.views.TabBarScrollView>

   <co.uk.gauntface.android.admob.views.SlidingLayout android:layout_width="fill_parent"
    android:id="@+id/AccountSummarySlidingLayout" android:layout_weight="1"
    android:layout_height="wrap_content" android:scrollbars="none" android:fadingEdge="none"
    android:fillViewport="true">
            </co.uk.gauntface.android.admob.views.SlidingLayout>

  </LinearLayout>

</LinearLayout>

Now the reason I’ve set FillViewPort to true is because of a similar issue here: LinearLayout not expanding inside a ScrollView
although this hasn’t fixed my issue.

The source code for the Activity is:

package co.uk.gauntface.android.admob;

import java.util.ArrayList;
import co.uk.gauntface.android.admob.models.RawSite;
import co.uk.gauntface.android.admob.models.SiteStat;
import co.uk.gauntface.android.admob.networking.AdmobDownloadListener;
import co.uk.gauntface.android.admob.networking.SiteStatService;
import co.uk.gauntface.android.admob.views.AccountSummaryAdapter;
import co.uk.gauntface.android.admob.views.SlidingLayout;
import co.uk.gauntface.android.admob.views.TabBarScrollView;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class AccountSummary extends AdmobActivity
{ 
 private final static String TAG = "admob";

 public static final String ACCOUNT_SUMMARY_INTENT_EXTRA_ID = "AccountSummaryIntentExtraID";

 private String mAccountID;
 private RawSite mRawSiteData;

 private Handler mHandler;
 private SiteStatService mSiteStatService;
 private ArrayList<SiteStat> mSiteStatData;

 private ActionBarHelper mActionBarHelper;

 private TextView mAppTitleTextView;
 private TabBarScrollView mTabBarScrollView;
 private SlidingLayout mSlidingLayout;
 private AccountSummaryAdapter mAdapter;

 /** Called when the activity is first created. */
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.account_summary);

  mAccountID = getIntent().getExtras().getString(ACCOUNT_SUMMARY_INTENT_EXTRA_ID);
  mSiteStatService = new SiteStatService(getApplicationContext());
  //mChartAdapter = new PointPositionAdapter(getApplicationContext());

  initActivity();

  setUpUI();

  if(getLastNonConfigurationInstance() != null) {
   mSiteStatData = (ArrayList<SiteStat>) getLastNonConfigurationInstance();
   mAdapter.setSiteStatData(mSiteStatData);
  } else {
   updateSiteStatData();
  }
 }

 /**public void onConfigurationChanged (Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  setContentView(R.layout.account_summary);

  setUpUI();
 }**/

 @Override
 public Object onRetainNonConfigurationInstance() {
  return mSiteStatData;
 }

 private void initActivity() {
  mHandler = new Handler() {
   public void handleMessage(Message msg) {
    switch(msg.arg1) {
    default:
     break;
    }
   }
  };

  mAdapter = new AccountSummaryAdapter(getApplicationContext(), new Integer[]{
   R.string.revenue,
   R.string.ecpm,
   R.string.requests,
   R.string.impressions,
   R.string.fill_rate,
   R.string.ctr
  });

  DatabaseManager dbManager = new DatabaseManager(getApplicationContext());
  dbManager.open();
  mRawSiteData = dbManager.getSite(mAccountID);
  dbManager.close();

 }

 private void setUpUI() {
  mActionBarHelper = new ActionBarHelper(this);

  mAppTitleTextView = (TextView) findViewById(R.id.AccountSummaryAppTitleTextView);
  mAppTitleTextView.setText(mRawSiteData.getSiteName());

  mTabBarScrollView = (TabBarScrollView) findViewById(R.id.AccountSummaryTabBarScrollView);
  mTabBarScrollView.setAdapter(mAdapter.getTabBarAdapter());
  mTabBarScrollView.setOnItemOnClickListener(mAdapter);

  mSlidingLayout = (SlidingLayout) findViewById(R.id.AccountSummarySlidingLayout);
  mSlidingLayout.setAdapter(mAdapter.getSlidingLayoutAdapter());
  mSlidingLayout.setOnDisplayChangeListener(mAdapter);
 }

 private void updateSiteStatData() {
  mActionBarHelper.incrementRequests();
  int daysToGet = getResources().getInteger(R.integer.account_summary_days);
  mSiteStatService.downloadDailySiteStats(daysToGet, mRawSiteData.getSiteID(), new AdmobDownloadListener() {

   public void onDownloadSuccess(Object obj) {
    mActionBarHelper.decrementRequests();
    mSiteStatData = (ArrayList<SiteStat>) obj;

    //mAdapter.setSiteStatData(mSiteStatData);
   }

   public void onDownloadError(int errorCode, String errorMsg) {
    mActionBarHelper.decrementRequests();
    displayErrorMessage(errorCode, errorMsg);
   }
  });
 }

 public void onClick(View v) {
  switch(v.getId())
  {
  case R.id.ActionBarRefreshImageButton:
   updateSiteStatData();
   break;
  }
 }
}

Which will display the views fine, however the SlidingLayout will actually appear blank (i.e it will not inflate the views contained in the LinearLayout.

The Source code for the SlidingLayout is:

package co.uk.gauntface.android.admob.views;

import co.uk.gauntface.android.admob.R;
import android.content.Context;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.Adapter;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

public class SlidingLayout extends HorizontalScrollView {

 private static final String TAG = "admob";

 private int mSelectedPosition;
 private int mNewSelectedPosition;
 private LinearLayout mContainerLinearLayout;

 private int mScaledTouchSlop;

 private float mPrevX;

 private int mItemCount;
 private boolean mIsTouchEventScroll;

 private SlidingLayoutAdapter mAdapter;
 private DataSetObserver mDataSetObserver;
 private OnDisplayChangeListener mDisplayChangeListener;

 public SlidingLayout(Context context) {
  super(context);

  constructor();
 }

 public SlidingLayout(Context context, AttributeSet attrs) {
  super(context, attrs);

  constructor();
 }

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

  constructor();
 }

 private void constructor() {
  Log.v(TAG, "SlidingLayout: constructor()");
  mSelectedPosition = 0;
  mNewSelectedPosition = 0;

  mItemCount = 0;

  mScaledTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  Log.v(TAG, "SlidingLayout: onTouchEvent()");
  int action = event.getAction();

  switch (action) {
  case MotionEvent.ACTION_DOWN:
   break;
  case MotionEvent.ACTION_MOVE:
   int deltaX = (int) (mPrevX - event.getX());
   scrollBy(deltaX, 0);
   break;
  case MotionEvent.ACTION_UP:
   animateToPosition();
  }

  mPrevX = event.getX();

  return true;
 }

 private void animateToPosition() {
  Log.v(TAG, "SlidingLayout: animateToPosition()");
  double scrollX = getScrollX();
  int screenWidth = getWidth();

  double ratio = scrollX / (double) screenWidth;
  int whichScreen = (int) Math.round(ratio);

  if(whichScreen >= 0 && whichScreen < mItemCount) {
   int newX = whichScreen * screenWidth;
   //int screenDiff = whichScreen - mDisplayedView;
   int screenDiff = whichScreen - mSelectedPosition;
   switch(screenDiff) {
   case -1:
    mNewSelectedPosition = mSelectedPosition - 1;
    break;
   case 0:
    mNewSelectedPosition = mSelectedPosition;
    break;
   case 1:
    mNewSelectedPosition = mSelectedPosition + 1;
    break;
   }

   if(mNewSelectedPosition < 0) {
    mNewSelectedPosition = 0;
   } else if(mNewSelectedPosition >= mItemCount) {
    mNewSelectedPosition = mItemCount - 1;
   }

   mIsTouchEventScroll = true;
   smoothScrollTo(newX, 0);
  }
 }

 public void setOnDisplayChangeListener(OnDisplayChangeListener changeListener) {
  mDisplayChangeListener = changeListener;
 }

 public void setAdapter(SlidingLayoutAdapter adapter) {
  Log.v(TAG, "SlidingLayout: setAdapter()");
  if(mContainerLinearLayout == null) {
   mContainerLinearLayout = new LinearLayout(getContext());
   mContainerLinearLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
   mContainerLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
   mContainerLinearLayout.setBackgroundColor(getContext().getResources().getColor(R.color.admob_color));

   addView(mContainerLinearLayout);
  }

  if(mAdapter != null) {
   mAdapter.unregisterDataSetObserver(mDataSetObserver);
  }

  mAdapter = adapter;

  if(mAdapter != null) {
   mDataSetObserver = new SlidingLayoutDataSetObserver();
   mAdapter.registerDataSetObserver(mDataSetObserver);

   mItemCount = mAdapter.getCount();
   mSelectedPosition = mAdapter.getSelectedPosition();
  } else {
   mItemCount = 0;
   mSelectedPosition = 0;

   return;
  }

  populateLayout();
 }

 // l is horizontal scroll origin, t is vertical
 /**protected void onScrollChanged (int l, int t, int oldl, int oldt) {
  super.onScrollChanged(l, t, oldl, oldt);
  if(mIsTouchEventScroll) {
   if(l % getWidth() == 0) {
    mIsTouchEventScroll = false;
    mSelectedPosition = mNewSelectedPosition;
    if(mDisplayChangeListener != null) {
     mDisplayChangeListener.onDisplayChange(l/getWidth());
    }
   }
  }
 }**/

 private void populateLayout() {
  Log.v(TAG, "SlidingLayout: populateLayout() - itemCount = "+mItemCount);
  if(mContainerLinearLayout != null) {
   mContainerLinearLayout.removeAllViews();
  }

  for(int i = 0; i < mItemCount; i++) {
   View v = mAdapter.getView(i, null, null);
   v.setMinimumWidth(getWidth());
   mContainerLinearLayout.addView(v);
  }

  invalidate();

  scrollTo(mSelectedPosition * getWidth(), 0);

  //View childView = mContainerLinearLayout.getChildAt(mSelectedPosition);
  //mContainerLinearLayout.invalidate();
  //childView.invalidate();
  Log.v(TAG, "SlidingLayout: populateLayout() scrollX - "+getScrollX());
  //Log.v(TAG, "SlidingLayout: populateLayout() childView.width() - "+childView.getWidth());
  Log.v(TAG, "SlidingLayout: populateLayout() getWidth() - "+getWidth());
  Log.v(TAG, "SlidingLayout: populateLayout() getHeight() - "+getHeight());
  //Log.v(TAG, "SlidingLayout: populateLayout() container.getWidth() - "+mContainerLinearLayout.getWidth());
  //Log.v(TAG, "SlidingLayout: populateLayout() container.getHeight() - "+mContainerLinearLayout.getHeight());
 }

 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  if(mAdapter != null) {
   mItemCount = mAdapter.getCount();
   mSelectedPosition = mAdapter.getSelectedPosition();
  }
  populateLayout();
 }

 public interface OnDisplayChangeListener {
  abstract void onDisplayChange(int position);
 }

 public interface SlidingLayoutAdapter extends Adapter {
  abstract int getSelectedPosition();
 }

 public class SlidingLayoutDataSetObserver extends DataSetObserver {
  public SlidingLayoutDataSetObserver() {
   super();
  }

  @Override
  public void onChanged() {
   Log.v(TAG, "SlidingLayout: onChanged()");
   mItemCount = mAdapter.getCount();
   mSelectedPosition = mAdapter.getSelectedPosition();
   populateLayout();
  }

  @Override
  public void onInvalidated() {
   // Data is invalid so we should reset our state
   //mItemCount = 0;
   //mSelectedPosition = 0;//mAdapter.getSelectedPosition();
   //Log.v(TAG, "SlidingLayout: onInvalidated() removeAllViews");
   //mContainerLinearLayout.removeAllViews();
   //invalidate();
   //populateLayout();
   //requestLayout();
   Log.v(TAG, "SlidingLayout: onInvalidated()");

   mItemCount = mAdapter.getCount();
   mSelectedPosition = mAdapter.getSelectedPosition();
   populateLayout();
  }
 }
}

Now what actually happens is the LinearLayout (Colored red) fills the entire view, but any calls to getWidth() and getHeight() on the LinearLayout return 0 (odd enough in it’s own right).

But if I touch a separate HorizontalScrollView (the mTabBarScrollView in the main activity), the SlidingLayout will actually resize / redraw / layout itself out. The same also occurs when a web service updates the adapter with data, which calls notifyDataSetChanged() (causing the resize / redraw / layout), however calling notifydatasetchanged() in the onCreate method of the activity doesn’t have the same effect.

The log on android shows no errors what so ever.

I’m at a loss as to what it could be / what I can do to force the layouts to update / inflate.

Any ideas / suggestions would be very welcome.

Cheers,
Matt

p.s. congratulations if you made it this far in the post 🙂

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T06:12:59+00:00Added an answer on May 28, 2026 at 6:12 am

    The solution in the end was to measure the child views and pass in a measure spec forcing them to be an exact width / height:

    v.measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
    

    The original code can be found on github https://github.com/gauntface/SideSwipeSnapViewLibrary

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to create an if statement in PHP that prevents a single post
Basically, what I'm trying to create is a page of div tags, each has
I have just tried to save a simple *.rtf file with some websites and
I have a French site that I want to parse, but am running into
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have a text area in my form which accepts all possible characters from
I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out
Does anyone know how can I replace this 2 symbol below from the string
I have a reasonable size flat file database of text documents mostly saved in
I am trying to loop through a bunch of documents I have to put

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.