gpt4 book ai didi

android - 使用新内容 : 刷新 ViewPager 的奇怪问题

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:31:51 30 4
gpt4 key购买 nike

我从 Web 服务接收数据,该数据被解析为 Application 中的对象类,这个对象在我的例子中是一个 Report类包含 Tabs 的列表应该填充 ViewPager .所以这个报告存储在currentReport Application 类中的参数。

每个选项卡应该是 ViewPager 中的一个页面.因此,当我第一次收到数据并对其进行解析时,一切都完美无缺,并且 View Pager 填充了正确的数据并呈现出来。

当我想得到一个新的 Report 时,我的问题就开始了从服务器刷新 ViewPager使用解析到 currentReport 中的新数据参数。

我的 ViewPager可以滑动并且有标签导航,所以当我尝试重新实例化 ViewPager 时与新 Report我看到添加到 tabHost 的标签数量正确.出于某种原因,新报告的 fragment 与之前报告的 fragment 重叠。因此,如果新报告中的选项卡数量大于上一个报告中的选项卡,那么除了部分新报告之外,我还可以看到上一个报告中的选项卡(例如,如果在第一个报告中我有一个选项卡,并且在新的中,我有 3 个,然后我看到前一个 fragment 的一个 fragment 和下一个 fragment 的最后 2 个 fragment )。

我从本教程开始我的开发并向其中添加了 smoe 代码: http://thepseudocoder.wordpress.com/2011/10/13/android-tabs-viewpager-swipe-able-tabs-ftw/

这是我的标签 Activity 代码:

public class TabsViewPagerFragmentActivity extends FragmentActivity implements    ViewPager.OnPageChangeListener, TabHost.OnTabChangeListener 
{
static final String TAG = TabsViewPagerFragmentActivity.class.getSimpleName();
private TabHost mTabHost;
private ViewPager mViewPager;
private HashMap<String, TabInfo> mapTabInfo;
public ViewPagerAdapter mPagerAdapter;
private TextView tvReportName, tvTabTitle;
private Button bBackToParameters;
private Dialog progressDialog;
private SGRaportManagerAppObj application;
private int numberOfTabs = 0;
private Display display;
public static final int POPUP_MARGIN = 6;
LeftSideMenu leftSideMenu;

public void NotifyTabActivityViewPagerAdapter()
{
mPagerAdapter.notifyDataSetChanged();
}

public ViewPagerAdapter getTabActivityViewPagerAdapter()
{
return mPagerAdapter;
}

public ViewPager getTabActivityViewPager()
{
return mViewPager;
}

public void setCurrentTabTitle (String title)
{
tvTabTitle.setText(title);
Log.d(TAG, "set tab title from activity: "+title);
}


/**
* Maintains extrinsic info of a tab's construct
*/
private class TabInfo
{
private String tag;
private Class<?> clss;
private Bundle args;
private Fragment fragment;

TabInfo(String tag, Class<?> clazz, Bundle args)
{
this.tag = tag;
this.clss = clazz;
this.args = args;
}
}

/**
* A simple factory that returns dummy views to the Tabhost
*/
class TabFactory implements TabContentFactory {

private final Context mContext;

/**
* @param context
*/
public TabFactory(Context context) {
mContext = context;
}

/** (non-Javadoc)
* @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
*/
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}

/** (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
*/
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
application = SGRaportManagerAppObj.getInstance();
display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
// Inflate the layout
setContentView(R.layout.tabs_screen_activity_layout);
tvTabTitle = (TextView) findViewById(R.id.tvTabName);
tvReportName = (TextView)findViewById(R.id.tvReportName);
tvReportName.setText(application.currentReport.getName()+ " - ");
bBackToParameters = (Button) findViewById(R.id.bBackToParameters);
leftSideMenu = (LeftSideMenu) findViewById(R.id.leftSideMenu);
applyOnClickListenerToLeftSideMenu();

findViewById(R.id.showLeftMenuButton).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Display d = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = d.getWidth();

View panel = findViewById(R.id.leftSideMenu);
View appPanel = findViewById(R.id.appLayout);
if (panel.getVisibility() == View.GONE){
appPanel.setLayoutParams(new LinearLayout.LayoutParams(width, LayoutParams.FILL_PARENT));
panel.setVisibility(View.VISIBLE);
applyOnClickListenerToLeftSideMenu();
}else{
ToggleButton button = (ToggleButton) findViewById(R.id.showLeftMenuButton);
button.setChecked(false);
panel.setVisibility(View.GONE);
}
}
});

// Initialise the TabHost
progressDialog = DialogUtils.createProgressDialog(this, this.getString(R.string.populating_view_pager));
progressDialog.show();

if (SGRaportManagerAppObj.getInstance().parametersRepository.getParametersRepository().size() == 0)
{
bBackToParameters.setText(R.string.back_to_report_list);
}
this.initialiseTabHost(savedInstanceState);

if (savedInstanceState != null) {
mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state
}
// Intialise ViewPager
this.intialiseViewPager();
progressDialog.dismiss();
}

/** (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
*/
protected void onSaveInstanceState(Bundle outState) {
outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected
super.onSaveInstanceState(outState);
}

/**
* Initialise ViewPager
*/
public void intialiseViewPager()
{

List<Fragment> fragments = new Vector<Fragment>();

// TabInfo tabInfo = null;

if (application.getCurrentDataSource().equals(DataSource.SSRS))
{
numberOfTabs = application.currentReport.getTabsList().size();
}
else if (application.getCurrentDataSource().equals(DataSource.SGRDL))
{
numberOfTabs = application.currentReport.getODTabsList().size();
Log.d(TAG, "CURRENT REPORT FROM VIEW PAGER: "+ application.currentReport.toString());
}

Log.d(TAG,"Current Tabs number from TabsViewPager activity: " +numberOfTabs);

if (application.getCurrentDataSource().equals(DataSource.SSRS))
{
for (int i = 0; i < numberOfTabs; i++)
{
Tab tempTab = application.currentReport.getTabsList().get(i);
if (tempTab.getTabTemplateId() == 7)
{
GridFragment gridFragment = new GridFragment(tempTab);
fragments.add(gridFragment);
}
else if (tempTab.getTabTemplateId() == 8)
{
NewChartFragment chartFragment = new NewChartFragment(tempTab, this);
fragments.add(chartFragment);
}
}
}
else if (application.getCurrentDataSource().equals(DataSource.SGRDL))
{
for (int i = 0; i < numberOfTabs; i++)
{
ODTab tempTab = application.currentReport.getODTabsList().get(i);
if (tempTab.getTabType().equals(ODGrid.XML_GRID_ELEMENT))
{
GridFragment gridFragment = GridFragment.newInstance(tempTab.getTabId());
fragments.add(gridFragment);
}
else if (tempTab.getTabType().equals(ODChart.XML_CHART_ELEMENT))
{
NewChartFragment chartFragment = NewChartFragment.newInstance(tempTab.getTabId());
fragments.add(chartFragment);
}
}
}

Log.d(TAG, "Current report fragments set to adapter: "+fragments.toString());
/*
if (this.mPagerAdapter == null)
{
this.mPagerAdapter = new ViewPagerAdapter(super.getSupportFragmentManager(), fragments);
}
else
{
this.mPagerAdapter.removeAllFragments();
this.mPagerAdapter.addFragmentsListToAdapter(fragments);
}
*/
this.mPagerAdapter = new ViewPagerAdapter(super.getSupportFragmentManager(), fragments);
this.mViewPager = (ViewPager)super.findViewById(R.id.pager);
// this.mViewPager.setAdapter(null);
this.mViewPager.setAdapter(this.mPagerAdapter);
this.mViewPager.setOffscreenPageLimit(0);
this.mViewPager.setOnPageChangeListener(this);
Log.d(TAG, "Adapter initialized!");
}

/**
* Initialise the Tab Host
*/
public void initialiseTabHost(Bundle args) {
mTabHost = (TabHost)findViewById(android.R.id.tabhost);

/*
//new edit
if (mTabHost.getChildCount() > 0)
{
mTabHost.removeAllViews();
}
*/

mTabHost.setup();
TabInfo tabInfo = null;
mapTabInfo = new HashMap<String, TabsViewPagerFragmentActivity.TabInfo>();
if (args != null)
{}
else
{
if (application.getCurrentDataSource().equals(DataSource.SSRS))
{
int numberOfTabs = application.currentReport.getTabsList().size();
for (int i = 0; i < numberOfTabs; i++)
{
Tab tempTab = application.currentReport.getTabsList().get(i);
if (tempTab.getTabTemplateId() == 7)
{
//GridFragment gridFragment = new GridFragment(tempTab);
TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), GridFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
}
else if (tempTab.getTabTemplateId() == 8)
{
TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), NewChartFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
}
}
}

else if (application.getCurrentDataSource().equals(DataSource.SGRDL))
{
int numberOfTabs = application.currentReport.getODTabsList().size();
for (int i = 0; i < numberOfTabs; i++)
{
ODTab tempTab = application.currentReport.getODTabsList().get(i);
// Log.d(TAG,"Crashed Tab type: "+ tempTab.getTabType());
if (tempTab.getTabType().equals(ODGrid.XML_GRID_ELEMENT))
{
//GridFragment gridFragment = new GridFragment(tempTab);
TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), GridFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
}
else if (tempTab.getTabType().equals(ODChart.XML_CHART_ELEMENT))
{
TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), NewChartFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
}
}
}
}
// Default to first tab
//this.onTabChanged("Tab1");
//
mTabHost.setOnTabChangedListener(this);
}

/**
* Add Tab content to the Tabhost
* @param activity
* @param tabHost
* @param tabSpec
* @param clss
* @param args
*/
private static void AddTab(TabsViewPagerFragmentActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo)
{
// Attach a Tab view factory to the spec
ImageView indicator = new ImageView(activity.getBaseContext());
indicator.setPadding(10, 10, 10, 10);
indicator.setImageResource(R.drawable.tab_select_icon_selector);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(10, 10, 10, 10);
indicator.setLayoutParams(lp);
tabSpec.setIndicator(indicator);
tabSpec.setContent(activity.new TabFactory(activity));
tabHost.addTab(tabSpec);
}

/** (non-Javadoc)
* @see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
*/
public void onTabChanged(String tag) {
//TabInfo newTab = this.mapTabInfo.get(tag);
int pos = this.mTabHost.getCurrentTab();
this.mViewPager.setCurrentItem(pos);
}

/* (non-Javadoc)
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrolled(int, float, int)
*/
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
// TODO Auto-generated method stub

}

/* (non-Javadoc)
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected(int)
*/
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
this.mTabHost.setCurrentTab(position);
}


/* (non-Javadoc)
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrollStateChanged(int)
*/
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub

}

这是我的适配器代码:

public class ViewPagerAdapter extends FragmentPagerAdapter 
{
private List<Fragment> fragments;

/**
* @param fm
* @param fragments
*/
public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}

/* (non-Javadoc)
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
*/

@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}

/* (non-Javadoc)
* @see android.support.v4.view.PagerAdapter#getCount()
*/

@Override
public int getCount() {
return this.fragments.size();
}

@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}

解析数据并更新 ViewPager 的我的 AsyncTask:

public class ParseSGRDLReportDataAsyncTask extends AsyncTask<String, Object, Report>{

static final String TAG = ParseSGRDLReportDataAsyncTask.class.getSimpleName();
private Activity activity;
private Exception exception;
private ResponseHandler responseHandler = new ResponseHandler();
private SGRaportManagerAppObj application;
private Dialog progressDialog;

public ParseSGRDLReportDataAsyncTask(LoginScrActivity activity) {
super();
this.activity = activity;
}

public ParseSGRDLReportDataAsyncTask(Activity currentActivity) {
super();
this.activity = currentActivity;
}

public void onPreExecute() {
application = SGRaportManagerAppObj.getInstance();
progressDialog = DialogUtils.createProgressDialog(activity, activity.getString(R.string.parse_data_dialog_message));
progressDialog.show();
}

@Override
protected Report doInBackground(String... params) {

String ReportDataString = params[0];
try{
return DataAccessManager.parseSGRDLReportData(ReportDataString);
}
catch (Exception e) {
exception = e;
return null;
}
}

@Override
public void onPostExecute(Report result) {
progressDialog.dismiss();

if (exception == null)
{
if (activity.getClass() == TabsViewPagerFragmentActivity.class)
{
application.currentReport = result;
Log.d(TAG, "Current report parsed is: "+result);

((TabsViewPagerFragmentActivity)activity).intialiseViewPager();

((TabsViewPagerFragmentActivity)activity).initialiseTabHost(null);

((TabsViewPagerFragmentActivity)activity).NotifyTabActivityViewPagerAdapter();

}
else
{
responseHandler.handleProcessSGRDLReportDataResult(result, activity);
}
}
else {
processException();
}
}

private void processException() {
Toast.makeText(activity, activity.getString(R.string.error_when_parsing_data), 3000).show();
}
}

答案:遵循 @Luksprog 针对所有遇到相同问题的人的建议,这是对我有用的最终结果,在 AsyncTask 中我需要添加以下内容:

if (activity.getClass() == TabsViewPagerFragmentActivity.class)
{
TabsViewPagerFragmentActivity tempActivity = ((TabsViewPagerFragmentActivity)activity);
application.currentReport = result;
Log.d(TAG, "Current report parsed is: "+result);
List<Fragment> frags = tempActivity.getTabActivityViewPagerAdapter().getFragments(); // getter method in your adapter
FragmentTransaction ft = tempActivity.getSupportFragmentManager().beginTransaction();
for (int i = 0; i < frags.size(); i++)
{
ft.remove(frags.get(i));
}
ft.commit();
tempActivity.intialiseViewPager();
tempActivity.getTabHost().getTabWidget().removeAllViews();
tempActivity.initialiseTabHost(null);
tempActivity.NotifyTabActivityViewPagerAdapter();
}

当主要的两点是从FragmentManager中删除之前添加的 fragment 时/SupportFragmentManager使用 FragmentTransactionViewPager 中显示正确的 fragment 集并从 TabWidget 中删除所有 View 在添加新的之前。

最佳答案

我不确定你是否解决了这个问题,如果是,请忽略我的回答。 Neron T 提供的链接很重要(更重要的是那里给出的建议不要引用外部适配器的 fragment )。

当您第二次使用新数据设置适配器时,由于 FragmentPagerAdapter 的实现方式,您将继续看到旧 fragment 。当您再次设置适配器时,适配器将首先运行 destroyItem() 方法,在该方法中,其 fragment 将从 ViewPager分离。接下来适配器将运行 instantiateItem() 方法。在此方法中,将针对 FragmentManager 执行检查,以查看是否有任何先前的 fragment 仍然不可用。此检查将找到旧 fragment (至少对于旧位置,这就是为什么你会得到新的位置 fragment ,而这在以前的情况下是不存在的,当时没有任何 fragment )因为它们只是从 ViewPager(但仍可通过 findFragmentByTag()FragmentManager 中使用)。如果在 FragmentManager 中找不到 fragment ,只有这样才会调用 getItem() 方法,从您的列表中检索 fragment 。

您应该修改您的代码以删除对这些 fragment 的列表引用,还有其他 ways to retrieve the fragments from the ViewPager (也不太理想)。作为快速修复,您可以尝试从 FragmentManager 中手动删除旧 fragment (就在设置新适配器之前)以强制 ViewPager.instantiateItem() 方法始终调用 getItem():

if (activity.getClass() == TabsViewPagerFragmentActivity.class) {
application.currentReport = result;
Log.d(TAG, "Current report parsed is: "+result);
ListFragment<Fragment> frags = ((ViewPagerAdapter)mViewPager.getAdapter()).getFragments(); // getter method in your adapter
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
for (int i = 0; i < mOldTmp.size(); i++) {
ft.remove(frags.get(i));
}
ft.commit();
((TabsViewPagerFragmentActivity)activity).intialiseViewPager();

((TabsViewPagerFragmentActivity)activity).initialiseTabHost(null);

((TabsViewPagerFragmentActivity)activity).NotifyTabActivityViewPagerAdapter();

}

这没有经过测试,所以试试看它是否有效。

关于android - 使用新内容 : 刷新 ViewPager 的奇怪问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16964669/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com