Android:ViewPager卡在视图之间

我有一个在碎片之间滑动的ViewPager。 我正在使用FragmentStatePagerAdapter将碎片提供给ViewPager。 如果用户以正常速度向左滑动,然后迅速向右滑动,则可以使ViewPager进入奇怪状态,显示多个碎片。

例如,如果用户在片段A上,然后以正常速度向左滑动到片段B,然后快速向右滑动以返回片段A,然后在屏幕上显示片段A和B.

任何人有什么想法,为什么这是发生或防止它的一个好办法?

以下是它的样子: 在这里输入图像说明

这是我在XML中的ViewPager定义:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.company.views.CustomActionBar android:id="@+id/customActionBar" android:layout_width="match_parent" android:layout_height="@dimen/height_actionbar" android:layout_alignParentTop="true"/> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/customActionBar"/> 

另外,我logging了我的onPageChangeListener()的输出,注意到当ViewPager卡在视图之间时,报告一个positionOffset为0.这是ViewPager的值,当它从STATE_DRAGGING过渡到STATE_SETTLING到STATE_IDLE时,奇怪的状态:

状态= 0 prevState:2位置:1 positionOffset:0.0

状态= 1 prevState:0位置:1 positionOffset:0.0

state = 2 prevState:1 position:1 positionOffset:0.4069444

状态= 0 prevState:2位置:2 positionOffset:0.0

所以看起来好像ViewPager是把错误的位置报告给我的。

完整的示例代码活动和适配器:

 public class ActivityBagelProfileViewer extends CustomAbstractFragmentActivity implements CustomActionBarContract, ListenerProgress, ListenerSync { public static final String EXTRA_BAGEL_INDEX = "BAGEL"; public static final int REQUEST_CODE_BAGEL_PROFILE_VIEWER = 4000; public static final int RESULT_GO_TO_PASS_FLOW = 12; public static final int RESULT_GO_TO_LIKE_FLOW = 14; public static final int RESULT_GO_TO_SEE_MORE_BAGELS = 16; private ViewPager mProfilesViewPager; private CustomActionBar mCustomActionBar; private int mViewPagerPosition; private DialogProgress mDialogProgress; private BagelViewPagerAdapter mAdapterBagelViewPager; private List<Bagel> mListBagels; @Override protected void onCreate(Bundle savedInstanceState) { Logger.d("ENTER"); super.onCreate(savedInstanceState); if (ManagerGive.IS_BRANCH_SESSION_OPEN == false) { ManagerGive.initializeBranchMetricsSession(); } setContentView(R.layout.activity_with_viewpager); mCustomActionBar = (CustomActionBar) findViewById(R.id.customActionBar); mCustomActionBar.setMenu(this); mProfilesViewPager = (ViewPager) findViewById(R.id.viewPager); if (getIntent().getExtras() != null) { mViewPagerPosition = getIntent().getExtras().getInt(EXTRA_BAGEL_INDEX, 0); } } @Override protected void onStop() { super.onStop(); ManagerGive.closeBranchMetricsSession(); } public void onIconClick(View view) { Logger.d("ENTER"); finishWithAnimation(); } private void finishWithAnimation() { setResult(RESULT_OK); finish(); overridePendingTransition(R.anim.slide_in_from_left, R.anim.slide_out_to_right); } @Override public void onBackPressed() { if (!super.handleBackPressedEvent()) { finishWithAnimation(); } } private void setupNewAdapter() { mListBagels = Bakery.getInstance().getManagerBagel().getCopyOfBagelsWithoutCurrent(); mAdapterBagelViewPager = new BagelViewPagerAdapter(getSupportFragmentManager(), mListBagels, this); mProfilesViewPager.setAdapter(mAdapterBagelViewPager); mProfilesViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { setActionBar(position); mViewPagerPosition = position; } @Override public void onPageScrollStateChanged(int state) { } }); mProfilesViewPager.setCurrentItem(mViewPagerPosition, false); } @Override protected void onResume() { Logger.d("ENTER"); super.onResume(); Bakery.getInstance().getManagerSyncData().addListener(this); if (mProfilesViewPager.getAdapter() == null) { Logger.d("Adapter null. Setting new adapter"); setupNewAdapter(); } else { if (mProfilesViewPager.getAdapter().getCount() != Bakery.getInstance().getManagerBagel().getCopyOfBagelsWithoutCurrent().size()) { Logger.d("Bagel list in Bakery changed size. Setting new adapter"); setupNewAdapter(); } } if (mListBagels.size() > 0) { setActionBar(mViewPagerPosition); mDialogProgress = new DialogProgress(this); } else { //kv Something has gone terribly wrong if we don't have any Bagels, just finish finish(); } } private void setActionBar(int bagelIndex) { Logger.d("bagelIndex=" + bagelIndex); Bagel bagel = mListBagels.get(bagelIndex); //kv If this is our current bagel and we haven't taken action yet, then show timer if (Bakery.getInstance().getManagerBagel().getCurrentBagel() == bagel && bagel.getAction() != Bagel.ACTION_LIKED && bagel.getAction() != Bagel.ACTION_PASSED) { Logger.d("Setting up #timer in action bar"); mCustomActionBar.startTimeLeftTimer(DateUtils.getMillisFromUtc(bagel.getEndDate()), this, new ListenerTimer() { @Override public void onTimerExpired() { Logger.d("ENTER"); Bakery.getInstance().getManagerSyncData().performSync(null, false); } }, mCustomActionBar.getTextViewTimeLeft(), R.string.timer_blank); mCustomActionBar.setLabel(R.string.time_left); mCustomActionBar.hideTitle(); } //kv Otherwise show date else { mCustomActionBar.setTitle(DateUtils.getLocalizedDateFromStringDate(bagel.getStartDate(), DateUtils.DATE_WITH_TIME_PATTERN)); mCustomActionBar.stopTimeLeftTimer(); mCustomActionBar.hideTimeLeft(); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(EXTRA_BAGEL_INDEX, mViewPagerPosition); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { Logger.d("ENTER"); super.onRestoreInstanceState(savedInstanceState); if (savedInstanceState.containsKey(EXTRA_BAGEL_INDEX)) { mViewPagerPosition = savedInstanceState.getInt(EXTRA_BAGEL_INDEX); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Logger.d("requestCode=" + requestCode + ", resultCode=" + resultCode + ", data=" + data); switch (requestCode) { case ActivityBeanShop.REQUEST_CODE: if (resultCode == Activity.RESULT_OK && data != null) { //fp user purchased sufficient beans to resume their transaction PurchaseType interruptedPurchaseType = (PurchaseType) data.getSerializableExtra(ActivityBeanShop.EXTRA_PURCHASE_TYPE); switch (interruptedPurchaseType) { case BONUS_BAGEL: case OPEN_SESAME: case REMATCH: Bundle bundle = new Bundle(); bundle.putSerializable(ManagerPurchase.EXTRA_PURCHASE_TYPE, interruptedPurchaseType); ManagerEvents.notifyListeners(EventType.BEAN_TRANSACTION_FOR_FEATURE_UNLOCK_COMPLETE, bundle); Logger.d("Notified listeners about #purchase bean transaction, can now resume feature #purchase"); break; default: Logger.w("Unrecognized purchase type: " + interruptedPurchaseType.getItemName()); } } break; default: Logger.w("Could not recognize code: " + requestCode); } } @Override public int getTitleId() { return R.string.bagel_action_checked; } @Override public int getIconId() { return R.drawable.selector_icon_up; } @Override public void showProgress(int stringId) { mDialogProgress.setText(stringId); mDialogProgress.show(); } @Override public void dismissProgress() { ViewUtils.safelyDismissDialog(mDialogProgress); } public void setActionBar() { setActionBar(mViewPagerPosition); } @Override public void onSyncComplete() { Logger.d("ENTER"); mListBagels = Bakery.getInstance().getManagerBagel().getCopyOfBagelsWithoutCurrent(); mAdapterBagelViewPager.setBagels(mListBagels); } public boolean isShowingThisBagel(Bagel bagel) { Bagel currentlyShownBagel = mListBagels.get(mViewPagerPosition); return bagel == currentlyShownBagel; } private static class BagelViewPagerAdapter extends FragmentStatePagerAdapter { private List<Bagel> mBagels; private ListenerProgress mListenerProgress; public BagelViewPagerAdapter(FragmentManager fragmentManager, List<Bagel> bagels, ListenerProgress listenerProgress) { super(fragmentManager); Logger.d("bagels=" + bagels); this.mBagels = bagels; mListenerProgress = listenerProgress; } @Override public Fragment getItem(int i) { Logger.d("i=" + i); UserProfile myProfile = Bakery.getInstance().getManagerUserProfile().getMyOwnProfile(); FragmentProfile fragment = FragmentProfile.newInstance(mBagels.get(i), false, myProfile); fragment.setListenerProgress(mListenerProgress); return fragment; } @Override public int getCount() { return mBagels.size(); } public void setBagels(List<Bagel> bagels) { mBagels = bagels; notifyDataSetChanged(); } } } 

这里是每个碎片布局的XML布局代码(不得不削减一些SO SO字符限制的B / C):

 <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/scrollView"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="-0.5dp" android:orientation="vertical" android:animateLayoutChanges="true" android:id="@+id/profile_top_container"> <!-- Photos section with pager/carousel --> <FrameLayout android:id="@+id/photoViewpagerContainer" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.coffeemeetsbagel.views.CustomAsShitViewPager android:id="@+id/pager_profile_images" xmlns:android="http://schemas.android.com/apk/res/android" app:aspectRatio="@integer/photo_ratio_height_over_width" android:layout_width="match_parent" android:layout_height="wrap_content"/> <LinearLayout android:id="@+id/linearLayout_bulletsAndFriendsContainer" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="bottom"> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/textView_stamp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="invisible" app:customFont="Raleway-Bold.ttf" android:layout_gravity="end" android:textSize="@dimen/text_stamp" android:paddingTop="@dimen/margin_large" android:layout_marginEnd="@dimen/margin_xxxxxsmall" android:layout_marginRight="@dimen/profile_margin_smaller"/> <!-- photo circle indicators --> <com.viewpagerindicator.CirclePageIndicator android:id="@+id/bullet_indicators" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/circle_indicator_margin_bottom" android:clickable="false" app:fillColor="@color/blue_cmb" app:pageColor="@color/gray_background" app:radius="@dimen/circle_indicator_radius" app:strokeWidth="0dp"/> <!-- container for mutual friends strip --> <RelativeLayout android:id="@+id/relativeLayout_mutual_friends_container" android:layout_width="match_parent" android:layout_height="@dimen/baseline_grid_component_touchable" android:background="@color/white_transparent" android:visibility="gone"> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/textView_mutual_friends_label" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" style="@style/profile_mutual_friends_text"/> <LinearLayout android:id="@+id/linearLayout_mutual_friends_icons" android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_marginEnd="@dimen/baseline_grid_small" android:layout_marginRight="@dimen/baseline_grid_small" android:layout_centerVertical="true"> <ImageView android:id="@+id/imageView_icon0" android:layout_width="@dimen/baseline_grid_component_touchable" android:layout_height="@dimen/baseline_grid_component_touchable" android:padding="@dimen/typography_smallest" android:background="@color/transparent" android:visibility="gone"/> <ImageView android:id="@+id/imageView_icon1" android:layout_width="@dimen/baseline_grid_component_touchable" android:layout_height="@dimen/baseline_grid_component_touchable" android:background="@color/transparent" android:padding="@dimen/typography_smallest" android:visibility="gone"/> <ImageView android:id="@+id/imageView_icon2" android:layout_width="@dimen/baseline_grid_component_touchable" android:layout_height="@dimen/baseline_grid_component_touchable" android:background="@color/transparent" android:padding="@dimen/typography_smallest" android:visibility="gone"/> </LinearLayout> </RelativeLayout> </LinearLayout> </FrameLayout> <!-- Buttons section with User Actions for pass / like--> <LinearLayout android:id="@+id/linearLayout_buttons_pass_like" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/baseline_grid_smaller" android:layout_marginLeft="@dimen/baseline_grid_small" android:layout_marginRight="@dimen/baseline_grid_small" android:layout_marginTop="@dimen/baseline_grid_medium" android:orientation="horizontal" android:visibility="gone"> <ImageView android:id="@+id/button_pass" android:layout_width="0dp" android:layout_height="@dimen/profile_action_button_height" android:layout_weight="1" android:background="@drawable/ripple_button_pass" android:clickable="true" android:src="@drawable/icon_pass_pressed" android:scaleType="center" android:layout_marginRight="@dimen/margin_small"/> <ImageView android:id="@+id/button_like" android:layout_width="0dp" android:layout_height="@dimen/profile_action_button_height" android:layout_weight="1" android:background="@drawable/ripple_button_like" android:clickable="true" android:src="@drawable/icon_like_pressed" android:scaleType="center" android:layout_marginLeft="@dimen/margin_small"/> </LinearLayout> <!-- Buttons section with User Actions for rematch / give--> <LinearLayout android:id="@+id/linearLayout_buttons_rematch_give" android:layout_width="match_parent" android:layout_height="@dimen/give_ten_button_height" android:layout_marginBottom="@dimen/baseline_grid_smaller" android:layout_marginLeft="@dimen/baseline_grid_small" android:layout_marginRight="@dimen/baseline_grid_small" android:layout_marginTop="@dimen/baseline_grid_medium" android:orientation="horizontal" android:gravity="center" android:visibility="gone"> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/textView_rematch" android:layout_width="@dimen/zero_dip" android:layout_height="match_parent" android:layout_marginRight="@dimen/give_take_button_margin_side" android:layout_weight="1" style="@style/button_give_take_rematch" android:text="@string/rematch"/> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/text_view_give_with_rematch" android:layout_width="@dimen/zero_dip" android:layout_weight="1" android:layout_height="match_parent" style="@style/button_give_take_rematch" android:text="@string/give"/> </LinearLayout> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/textView_they_like_you" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableLeft="@drawable/icon_like_alert" android:drawablePadding="@dimen/margin_xxsmall" style="@style/profile_info_item_value" android:layout_marginLeft="@dimen/margin_med" android:paddingTop="@dimen/baseline_grid_smaller"/> <ViewStub android:id="@+id/viewStub_profile_feedback" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout="@layout/profile_feedback"/> <!-- Profile information table --> <!-- Name --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/profile_info_item_layout_margins" android:paddingTop="@dimen/baseline_grid_smaller" android:orientation="horizontal"> <com.coffeemeetsbagel.views.CustomTextView android:text="@string/profile_info_label_name" style="@style/profile_info_item_label" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"/> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/profile_info_value_name" style="@style/profile_info_item_value" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2"/> </LinearLayout> <!-- Age --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/profile_info_item_layout_margins" android:orientation="horizontal"> <com.coffeemeetsbagel.views.CustomTextView android:text="@string/profile_info_label_age" style="@style/profile_info_item_label" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/profile_info_value_age" style="@style/profile_info_item_value" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2"/> </LinearLayout> <!-- Location --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/profile_info_item_layout_margins" android:orientation="horizontal"> <com.coffeemeetsbagel.views.CustomTextView android:text="@string/location" style="@style/profile_info_item_label" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/profile_info_value_location" style="@style/profile_info_item_value" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2"/> </LinearLayout> <!-- Ethnicity --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/profile_info_item_layout_margins" android:orientation="horizontal"> <com.coffeemeetsbagel.views.CustomTextView android:text="@string/profile_info_label_ethnicity" style="@style/profile_info_item_label" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/profile_info_value_ethnicity" style="@style/profile_info_item_value" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2"/> </LinearLayout> <!-- Height --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/profile_info_item_layout_margins" android:orientation="horizontal"> <com.coffeemeetsbagel.views.CustomTextView android:text="@string/profile_info_label_height" style="@style/profile_info_item_label" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/profile_info_value_height" style="@style/profile_info_item_value" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2"/> </LinearLayout> <!-- Religion --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/profile_info_item_layout_margins" android:orientation="horizontal"> <com.coffeemeetsbagel.views.CustomTextView android:text="@string/profile_info_label_religion" style="@style/profile_info_item_label" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/profile_info_value_religion" style="@style/profile_info_item_value" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2"/> </LinearLayout> <!-- Occupation --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/profile_info_item_layout_margins" android:orientation="horizontal"> <com.coffeemeetsbagel.views.CustomTextView android:text="@string/profile_info_label_occupation" style="@style/profile_info_item_label" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <com.coffeemeetsbagel.views.CustomTextView android:id="@+id/profile_info_value_occupation" style="@style/profile_info_item_value" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2"/> </LinearLayout> <!-- Employer --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/profile_info_item_layout_margins" android:orientation="horizontal"> 

Solutions Collecting From Web of "Android:ViewPager卡在视图之间"

我注意到,我看到这个问题,如果我有animateLayoutChanges给出一些animation。 只要在xml文件中禁用它,就可以防止页面卡在中间。

尝试下面的示例代码,并根据您的要求修改它(我猜你正在加载主UI线程上的图像,而不是caching它,只是一个猜测)。 在这段代码中,我正在从互联网下载和caching图像:创build一个名为SomeFragTest的Activity类

 import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import android.app.ActivityManager; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.util.LruCache; import android.support.v4.view.ViewPager; import android.util.Log; import android.widget.ImageView; public class SomeFragTest extends FragmentActivity{ private LruCache<String, Bitmap> cache; private List<String> strings; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_layout); ViewPager mViewPager = (ViewPager)findViewById(R.id.viewPager); strings=new ArrayList<String>(); setData(); int memClass = ( ( ActivityManager )getSystemService( Context.ACTIVITY_SERVICE ) ).getMemoryClass(); int cacheSize = 1024 * 1024 * memClass / 8; cache=new LruCache<String, Bitmap>(cacheSize){ @Override protected int sizeOf(String key, Bitmap value) { return value.getByteCount()/1024; } }; mViewPager.setOffscreenPageLimit(strings.size()); mViewPager.setAdapter(new MyPageAdapter(getSupportFragmentManager())); } private void setData() { for (int i = 1; i <= 10; i++) { strings.add("http://img.androidcookie.com/android/0011ff.png&text="+i); } } public void loadBitmap(int position , ImageView imageView) { imageView.setImageResource(R.drawable.ic_launcher); imageView.setTag(strings.get(position)); BitmapDownloaderTask task = new BitmapDownloaderTask(imageView); task.execute(strings.get(position)); } class MyPageAdapter extends FragmentPagerAdapter { public MyPageAdapter(FragmentManager fm) { super(fm); // TODO Auto-generated constructor stub } @Override public Fragment getItem(int arg0) { Fragment fragment=new ChildFrag(); Bundle bundle=new Bundle(); bundle.putInt("POS", arg0); fragment.setArguments(bundle); return fragment; } @Override public int getCount() { return strings.size(); } } class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> { public String url; private final WeakReference<ImageView> imageViewReference; public BitmapDownloaderTask(ImageView imageView) { imageViewReference = new WeakReference<ImageView>(imageView); } @Override // Actual download method, run in the task thread protected Bitmap doInBackground(String... params) { // params comes from the execute() call: params[0] is the url. url=params[0]; if(cache.get(url)!=null){ Log.e("FROM ", "CACHE"); return cache.get(url); } return downloadBitmap(params[0]); } private Bitmap downloadBitmap(String url) { Log.e("FROM ", "URL"); HttpClient client=new DefaultHttpClient(); //final AndroidHttpClient client = AndroidHttpClient.newInstance("Android"); final HttpGet getRequest = new HttpGet(url); try { HttpResponse response = client.execute(getRequest); final int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url); return null; } final HttpEntity entity = response.getEntity(); if (entity != null) { InputStream inputStream = null; try { inputStream = entity.getContent(); //final Bitmap bitmap = BitmapFactory.decodeStream(inputStream); return decodeBitmapWithGiveSizeFromResource(inputStream); } finally { if (inputStream != null) { inputStream.close(); } entity.consumeContent(); } } } catch (Exception e) { // Could provide a more explicit error message for IOException or IllegalStateException getRequest.abort(); Log.w("ImageDownloader", "Error while retrieving bitmap from " + url); Log.e("ERROR", " " +e.getLocalizedMessage()); } finally { if (client != null) { //client.close(); } } return null; } /***************/ private void copy(InputStream inputStream,ByteArrayOutputStream arrayOutputStream) { byte[] buffer = new byte[1024]; int len; try { while ((len = inputStream.read(buffer)) > -1 ) { arrayOutputStream.write(buffer, 0, len); } arrayOutputStream.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private Bitmap decodeBitmapWithGiveSizeFromResource(InputStream inputStream) { //BufferedInputStream bufferedInputStream=new BufferedInputStream(inputStream); final BitmapFactory.Options options = new BitmapFactory.Options(); ByteArrayOutputStream out = new ByteArrayOutputStream(); copy(inputStream,out); InputStream in2 = new ByteArrayInputStream(out.toByteArray()); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(inputStream, null, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; Bitmap bitmap=BitmapFactory.decodeStream(in2,null, options); try { inputStream.close(); in2.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return scaleDown(bitmap,false); } private Bitmap scaleDown(Bitmap realImage, boolean filter) { Bitmap newBitmap = Bitmap.createScaledBitmap(realImage, 100, 100, filter); Bitmap output = Bitmap.createBitmap(newBitmap.getWidth(), newBitmap .getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, newBitmap.getWidth(), newBitmap.getHeight()); final RectF rectF = new RectF(rect); final float roundPx = 10; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(newBitmap, rect, rect, paint); return output; } private int calculateInSampleSize(BitmapFactory.Options options) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > 100 || width > 100) { final int halfHeight = height / 2; final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a power of 2 and keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) >100 && (halfWidth / inSampleSize) >100) { inSampleSize *= 2; } } return inSampleSize; } @Override // Once the image is downloaded, associates it to the imageView protected void onPostExecute(Bitmap bitmap) { if (isCancelled()) { bitmap = null; } if (imageViewReference != null) { cache.put(url, bitmap); ImageView imageView = imageViewReference.get(); // BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView); // Change bitmap only if this process is still associated with it if (((String)imageView.getTag()).equalsIgnoreCase(url)) { imageView.setImageBitmap(bitmap); } } } } } 

在此之后,为其创buildxml,名为activity_layout

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> 

现在我们创build了我们想要在ViewPager中膨胀的Fragment类:创build一个名为ChildFrag的类,如下所示

 import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; public class ChildFrag extends Fragment { private int index; private ImageView imageView; @Override @Nullable public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragtest, container, false); index = getArguments().getInt("POS"); ((TextView) view.findViewById(R.id.textView1)).setText("" + index); imageView = (ImageView) view.findViewById(R.id.imageView1); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); ((SomeFragTest) getActivity()).loadBitmap(index, imageView); } } 

现在我们创build片段的xml为fragtest:

  <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> </LinearLayout> 

在AndroidManifest.xml中添加以下权限

  <uses-permission android:name="android.permission.INTERNET" /> 

现在,我认为有一个布局的宽度问题。 到目前为止,我只看到一个嫌疑人,还有一个未知的属性

 app:aspectRatio="@integer/photo_ratio_height_over_width" 

在UI元素<com.coffeemeetsbagel.views.CustomAsShitViewPager

显然,在库/代码CustomAsShitViewPager中有一个自定义属性,至less可以发布与aspectRatio相关的代码。

我只是意识到你在主Activity中的onCreate ()方面做了大量的UI工作。 在onCreateView ()中做这个工作比较合适。 我相信Android框架没有完成onCreate ()中的UI工作,因此你看到不完整的UI渲染。 我知道这在Android文档中没有明确说明。 如果您检查其他SOpost或示例项目,其他开发人员会在onCreate ()中做很less的UI工作。 至less,布局比你的简单。

这是我的build议。 使用onCreateView ()方法中的Activity或Fragment中的fragtest布局,使用post上列出的ID。 注意override方法只是膨胀。 示例代码:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragtest, container, false); } 

在片段上,使用post中列出的ID开始访问UI元素和ViewPager。 示例代码:

 @Override public void onViewCreated(View view, Bundle savedInstanceState) { mProfilesViewPager = (ViewPager) findViewById(R.id.viewPager); ... 

现在,我怀疑有两种方法。

1)在片段代码中:

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

注意: getCount()应该返回片段的数量而不是列表的大小。 我不知道你会有多less碎片。 也许你必须跟踪适配器。

2)另外,我怀疑getItem()方法和newInstance ()的使用。 相关的具体代码:

 FragmentProfile fragment = FragmentProfile.newInstance(mBagels.get(i),... 

备注

  • 根据Google的网页FragmentStatePagerAdapter , newInstance方法应该创build一个新的片段,可能是因为当FragmentStatePagerAdapter在内存中没有片段时, OR还是从内存中释放。

  • 也许张贴与FragmentProfile.newInstance相关的代码,特别是如果你不同意我上面的声明。