欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android Viewpager實現無限循環(huán)輪播圖

 更新時間:2021年01月02日 09:19:04   作者:xia236326  
這篇文章主要為大家詳細介紹了Android Viewpager實現無限循環(huán)輪播圖,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

在網上找了很多viewpager實現圖片輪播的,但是大多數通過以下方式在PagerAdapter的getCount()返回一個無限大的數,來實現 偽無限

@Override
 public int getCount() {
  return Integer.MAX_VALUE;//返回一個無限大的值,可以 無限循環(huán)
 }

雖然通過這種方式是能達到效果,但是從嚴格意義上來說并不是真正的無限。

假如有五張輪播圖 item的編號為(0,1,2,3,4) 要想實現 無限循環(huán)  我們在這五張的頭部和尾部各加一張即(5+2)張,item編號為(0,1,2,3,4,5,6)其中編號為0,6的兩張不做展示只是為了做循環(huán)輪播的鋪墊,使得播放更加平滑。

1、當我們從編號為5 右滑的時候到了編號6 這時候就將當前頁面設置為1

2、當我們從編號為1左滑的時候到了編號0  這時候就將當前頁面設置為5

這么做之后就可以實現無限輪播  怎么保證從編號6跳轉編號1的時候不出現頁面停頓 突然跳到下一頁的現象呢?

public Object instantiateItem (ViewGroup container, int position)

在指定的位置創(chuàng)建頁面;適配器負責添加view到這個容器中,然而它只保證在finishUpdate(ViewGroup)返回時才完成。

public void destroyItem (ViewGroup container, int position, Object object)

刪除指定位置的頁面;適配器負責從view容器中刪除view,然而它只保證在finishUpdate(ViewGroup)返回時才完成。

所以說 重點就在于finishUpdate(ViewGroup)這個方法 其實無論是創(chuàng)建view添加到容器中  還是 銷毀view 都是在此方法結束之后執(zhí)行的

換句話說  就是 我在這個方法里讓頁面完成從 編號5跳轉到編號1 或者從編號1跳轉到編號5,此方法完成時 視圖還未完成創(chuàng)建或者 銷毀 這樣也就不會出現 頁面停頓 突然跳到下一頁的現象。

@Override
 public void finishUpdate(ViewGroup container) {
  super.finishUpdate(container);
 
  int position = viewPager.getCurrentItem();
  
  if (position == 0) {
   position = simpleDraweeViewList.size() - 2;
   viewPager.setCurrentItem(position,false);
  } else if (position == simpleDraweeViewList.size() - 1) {
   position = 1;
   viewPager.setCurrentItem(position,false);
  }
 }

話不多說,上代碼:

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context=".MainActivity">
 
 <FrameLayout
  android:id="@+id/frameLayout"
  android:layout_width="0dp"
  android:layout_height="200dp"
  app:layout_constraintEnd_toEndOf="parent"
  app:layout_constraintHorizontal_bias="0.0"
  app:layout_constraintStart_toStartOf="parent"
  app:layout_constraintTop_toTopOf="parent">
 
  <android.support.v4.view.ViewPager
   android:id="@+id/viewPager"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:layout_editor_absoluteX="8dp"
   tools:layout_editor_absoluteY="0dp" />
 
  <LinearLayout
   android:layout_width="match_parent"
   android:layout_height="35dip"
   android:layout_gravity="bottom"
   android:background="#33000000"
   android:gravity="center_vertical"
   android:orientation="horizontal"
   android:weightSum="10">
 
   <TextView
    android:id="@+id/tv_pager_title"
    android:layout_width="0dp"
    android:layout_height="35dip"
    android:layout_weight="8"
    android:gravity="center_vertical"
    android:paddingLeft="8dip"
    android:text="加載圖片輪播失敗"
    android:textColor="@android:color/white" />
 
   <LinearLayout
    android:id="@+id/lineLayout_dot"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_marginRight="5dp"
    android:layout_weight="2"
    android:gravity="center|right"
    android:orientation="horizontal"
    android:paddingLeft="3dp"
    android:paddingRight="3dp" />
 
  </LinearLayout>
 
 </FrameLayout>
 
</android.support.constraint.ConstraintLayout>

最主要的PagerAdapter:

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
 
import com.facebook.drawee.view.SimpleDraweeView;
 
import java.util.List;
 
public class ImagesPagerAdapter extends PagerAdapter {
 private List<SimpleDraweeView> simpleDraweeViewList;
 private ViewPager viewPager;
 private Context context;
 
 private SimpleDraweeView simpleDraweeView;
 
 public ImagesPagerAdapter(List<SimpleDraweeView> simpleDraweeViewList, ViewPager viewPager, Context context) {
  this.simpleDraweeViewList = simpleDraweeViewList;
  this.viewPager = viewPager;
  this.context = context;
 }
 
 @Override
 public int getCount() {
 return simpleDraweeViewList.size();
 }
 
 //刪除指定位置的頁面;適配器負責從view容器中刪除view,然而它只保證在finishUpdate(ViewGroup)返回時才完成。
 @Override
 public void destroyItem(ViewGroup container, int position, Object object) {
  // 把ImageView從ViewPager中移除掉
  viewPager.removeView(simpleDraweeViewList.get(position));
  //super.destroyItem(container, position, object);
 }
 
 //是否獲取緩存
 @Override
 public boolean isViewFromObject(View view, Object object) {
  return view == object;
 }
 
 
 //實例化Item
 //在指定的位置創(chuàng)建頁面;適配器負責添加view到這個容器中,然而它只保證在finishUpdate(ViewGroup)返回時才完成。
 @Override
 public Object instantiateItem(ViewGroup container, int position) {
  simpleDraweeView = simpleDraweeViewList.get(position);
  viewPager.addView(simpleDraweeView);
  return simpleDraweeView;
 }
 
 @Override
 public int getItemPosition(Object object) {
  return POSITION_NONE;
 }
 
 //無論是創(chuàng)建view添加到容器中 還是 銷毀view 都是在此方法結束之后執(zhí)行的
 @Override
 public void finishUpdate(ViewGroup container) {
  super.finishUpdate(container);
 
  int position = viewPager.getCurrentItem();
  
  if (position == 0) {
   position = simpleDraweeViewList.size() - 2;
   viewPager.setCurrentItem(position,false);
  } else if (position == simpleDraweeViewList.size() - 1) {
   position = 1;
   viewPager.setCurrentItem(position,false);
  }
 }
 
 
 
/* private int mChildCount = 0;
 @Override
 public void notifyDataSetChanged() {
  mChildCount = getCount();
  super.notifyDataSetChanged();
 }
 @Override
 public int getItemPosition(Object object) {
  if (mChildCount > 0) {
   mChildCount--;
   Log.e("image","getItemPosition");
   return POSITION_NONE;
  }
  return super.getItemPosition(object);
 }*/
}
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
 
import com.facebook.drawee.view.SimpleDraweeView;
 
import java.util.ArrayList;
import java.util.List;
 
 
 
public class ImageCarousel {
 private Context context;
 private ViewPager viewPager;
 private TextView tvTitle;
 private LinearLayout dotsRoot;
 private int time;
 
 
 private List<View> dots;//小點
 private int previousPosition = 1;//前一個被選中的position
 private List<SimpleDraweeView> simpleDraweeViewList;
 private String[] titles;//標題數組
 
 private ImagesPagerAdapter adapter;
 
 private AutoPlayThread autoPlayThread;
 private volatile boolean isExit = true;
 
 private static final int FIRST_PAGE = 1;
 
 
 public ImageCarousel(Context context, ViewPager viewPager, TextView tvTitle,
       List<View> dots, int time) {
  this.context = context;
  this.viewPager = viewPager;
  this.tvTitle = tvTitle;
  this.dots = dots;
  this.time = time;
  Log.e("image", "構造方法");
 }
 
 
 
 /**
  * 傳入數據
  *
  * @param simpleDraweeViewList SimpleDraweeView集合
  * @param titles    標題數組
  * @return this 本身
  */
 public ImageCarousel init(List<SimpleDraweeView> simpleDraweeViewList, String[] titles) {
  this.simpleDraweeViewList = simpleDraweeViewList;
  this.titles = titles;
  Log.e("image", "init");
  autoPlayThread = new AutoPlayThread();
 
  return this;
 }
 
 /**
  * 重新加載,有待考驗...
  *
  * @param simpleDraweeViewList SimpleDraweeView集合
  * @param titles    標題數組
  */
 public void reload(List<SimpleDraweeView> simpleDraweeViewList, String[] titles) {
  init(simpleDraweeViewList, titles);
  previousPosition = 0;
  start();
 }
 
 /**
  * 設置設配器,并實現輪播功能
  */
 public void start() {
  if (adapter != null) {
   adapter = null;
  }
  adapter = new ImagesPagerAdapter(this.simpleDraweeViewList, viewPager, context);
  viewPager.setAdapter(adapter);
  viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
   @Override
   public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
 
   }
 
   //當被選擇
   @Override
   public void onPageSelected(int position) {
 
    int currentPosition = 1;
    if (position == simpleDraweeViewList.size() - 1) {
     // 設置當前值為1
     currentPosition = FIRST_PAGE;
    } else if (position == 0) {
     // 如果索引值為0了,就設置索引值為倒數第二個
     currentPosition = simpleDraweeViewList.size() - 2;
    } else {
     currentPosition = position;
    }
 
    // 把當前選中的點給切換了, 還有描述信息也切換
    tvTitle.setText(titles[currentPosition]);//圖片下面設置顯示文本
    //設置輪播點 可設置成傳入的圖
 
    Log.d("dots", "previousPosition=" + previousPosition + " currentPosition=" + currentPosition);
    dots.get(previousPosition-1).setBackgroundResource(R.drawable.ic_dot_focused);
    dots.get(currentPosition-1).setBackgroundResource(R.drawable.ic_dot_normal);
    // 把當前的索引賦值給前一個索引變量, 方便下一次再切換.
    previousPosition = currentPosition;
   }
 
   @Override
   public void onPageScrollStateChanged(int state) {
 // SCROLL_STATE_IDLE :空閑狀態(tài) 
 // SCROLL_STATE_DRAGGING :滑動狀態(tài) 
 // SCROLL_STATE_SETTLING :滑動后滑翔的狀態(tài)
    if (state == ViewPager.SCROLL_STATE_DRAGGING) {
 
    } else if(state == ViewPager.SCROLL_STATE_IDLE){
  
 }
   }
  });
 
  setFirstLocation();
  //autoPlayThread.start();
 
 }
 
 /**
  * 設置剛打開app時顯示的圖片和文字
  */
 private void setFirstLocation() {
  tvTitle.setText(titles[0]);
  dots.get(0).setBackgroundResource(R.drawable.ic_dot_normal);
  viewPager.setCurrentItem(1);
 }
 
 /**
  * 設置是否輪播
  *
  * @param b
  */
 private void setAutoPlay(boolean b) {
  /*if (b && suspendRequested) {
   autoPlayThread.requestResume();
  } else if (!b){
   autoPlayThread.requestSuspend();
  }*/
 }
 
 
 public void stopAutoPlay() {
  if (autoPlayThread != null) {
   Log.e("thrad", "暫停");
   isExit = true;
   autoPlayThread.interrupt();
   autoPlayThread = null;
  }
 }
 
 /**
  * 請求繼續(xù)
  */
 public void startAutoPlay() {
  Log.e("thrad", "開始");
  isExit = false;
  autoPlayThread = null;
  autoPlayThread = new AutoPlayThread();
  autoPlayThread.start();
 }
 
 /**
  * 自動播放線程,添加暫停和繼續(xù)方法
  */
 class AutoPlayThread extends Thread {
 
  @Override
  public synchronized void run() {
   while (!isExit) {
    try {
     Thread.sleep(time);
    } catch (InterruptedException e) {
     Log.e("thrad", "強制請求退出線程");
     break;
    }
    ((Activity) context).runOnUiThread(new Runnable() {
     @Override
     public void run() {
      viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
     }
    });
 
    if (this.interrupted()) {
     Log.e("thrad", "已經是停止狀態(tài)了,我要退出了");
     break;
    }
   }
 
  }
 
 }
 
}

mainActivity.java:

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.LinearLayout;
import android.widget.TextView;
 
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.backends.pipeline.PipelineDraweeController;
import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.common.ResizeOptions;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
 
import java.util.ArrayList;
import java.util.List;
 
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
 
 // 圖片輪播控件
 private ViewPager mViewPager;
 private TextView mTvPagerTitle;
 private LinearLayout mLineLayoutDot;
 private ImageCarousel imageCarousel;
 private List<View> dots;//小點
 
 // 圖片數據,包括圖片標題、圖片鏈接、數據、點擊要打開的網站(點擊打開的網頁或一些提示指令)
 private List<ImageInfo> imageInfoList;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  initView();
  initEvent();
  imageStart();
 
 }
 
 @Override
 public void onClick(View v) {
 
 }
 
 /**
  * 初始化事件
  * 左右多添加一張圖片
  */
 private void initEvent() {
  imageInfoList = new ArrayList<>();
 imageInfoList.add(new ImageInfo(1, "圖片5,公告5啦啦啦啦", "", "/image/h%3D300/sign=73443062281f95cab9f594b6f9177fc5/72f082025aafa40fafb5fbc1a664034f78f019be.jpg", ""));
  imageInfoList.add(new ImageInfo(2, "圖片1,公告1啦啦啦啦", "", "/image/pic/item/6159252dd42a2834a75bb01156b5c9ea15cebf2f.jpg", ""));
  imageInfoList.add(new ImageInfo(3, "圖片2,公告2啦啦啦啦", "", "/image/h%3D300/sign=cfce96dfa251f3dedcb2bf64a4eff0ec/4610b912c8fcc3ce912597269f45d688d43f2039.jpg", ""));
  imageInfoList.add(new ImageInfo(4, "圖片3,公告3啦啦啦啦", "", "/image/pic/item/6a600c338744ebf85ed0ab2bd4f9d72a6059a705.jpg", ""));
  imageInfoList.add(new ImageInfo(5, "圖片4,公告4啦啦啦啦", "", "/image/h%3D300/sign=8ad802f3801001e9513c120f880e7b06/a71ea8d3fd1f4134be1e4e64281f95cad1c85efa.jpg", ""));
  imageInfoList.add(new ImageInfo(6, "圖片5,公告5啦啦啦啦", "", "/image/h%3D300/sign=73443062281f95cab9f594b6f9177fc5/72f082025aafa40fafb5fbc1a664034f78f019be.jpg", ""));
 imageInfoList.add(new ImageInfo(7, "圖片1,公告1啦啦啦啦", "", "/image/pic/item/6159252dd42a2834a75bb01156b5c9ea15cebf2f.jpg", ""));
 
 }
 
 /**
  * 初始化控件
  */
 private void initView() {
 
  mViewPager = findViewById(R.id.viewPager);
  mTvPagerTitle = findViewById(R.id.tv_pager_title);
  mLineLayoutDot = findViewById(R.id.lineLayout_dot);
 
 }
 
 private void imageStart() {
  //設置圖片輪播
  int[] imgaeIds = new int[]{R.id.pager_image1, R.id.pager_image2, R.id.pager_image3, R.id.pager_image4,
    R.id.pager_image5, R.id.pager_image6, R.id.pager_image7, R.id.pager_image8};
  String[] titles = new String[imageInfoList.size()];
  List<SimpleDraweeView> simpleDraweeViewList = new ArrayList<>();
 
  for (int i = 0; i < imageInfoList.size(); i++) {
   titles[i] = imageInfoList.get(i).getTitle();
   SimpleDraweeView simpleDraweeView = new SimpleDraweeView(this);
   simpleDraweeView.setAspectRatio(1.78f);
   // 設置一張默認的圖片
   GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(this.getResources())
     .setPlaceholderImage(ContextCompat.getDrawable(this, R.drawable.defult), ScalingUtils.ScaleType.CENTER_CROP).build();
   simpleDraweeView.setHierarchy(hierarchy);
   simpleDraweeView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
 
   //加載高分辨率圖片;
   ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(imageInfoList.get(i).getImage()))
     .setResizeOptions(new ResizeOptions(1280, 720))
     .build();
   PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
     //.setLowResImageRequest(ImageRequest.fromUri(Uri.parse(listItemBean.test_pic_low))) //在加載高分辨率圖片之前加載低分辨率圖片
     .setImageRequest(imageRequest)
     .setOldController(simpleDraweeView.getController())
     .build();
   simpleDraweeView.setController(controller);
 
   simpleDraweeView.setId(imgaeIds[i]);//給view設置id
   simpleDraweeView.setTag(imageInfoList.get(i));
   simpleDraweeView.setOnClickListener(this);
   titles[i] = imageInfoList.get(i).getTitle();
   simpleDraweeViewList.add(simpleDraweeView);
 
  }
 
  dots = addDots(mLineLayoutDot, fromResToDrawable(this, R.drawable.ic_dot_focused), simpleDraweeViewList.size());
  imageCarousel = new ImageCarousel(this, mViewPager, mTvPagerTitle, dots, 5000);
  imageCarousel.init(simpleDraweeViewList, titles)
    .startAutoPlay();
  imageCarousel.start();
 
 }
 
 
 /**
  * 動態(tài)添加一個點
  *
  * @param linearLayout 添加到LinearLayout布局
  * @param backgount 設置
  * @return 小點的Id
  */
 private int addDot(final LinearLayout linearLayout, Drawable backgount) {
  final View dot = new View(this);
  LinearLayout.LayoutParams dotParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
    ViewGroup.LayoutParams.WRAP_CONTENT);
  dotParams.width = 16;
  dotParams.height = 16;
  dotParams.setMargins(4, 0, 4, 0);
  dot.setLayoutParams(dotParams);
  dot.setBackground(backgount);
  dot.setId(View.generateViewId());
  ((Activity) this).runOnUiThread(new Runnable() {
   @Override
   public void run() {
    linearLayout.addView(dot);
   }
  });
 
  return dot.getId();
 }
 
 
 /**
  * 資源圖片轉Drawable
  *
  * @param context 上下文
  * @param resId 資源ID
  * @return 返回Drawable圖像
  */
 public static Drawable fromResToDrawable(Context context, int resId) {
  return ContextCompat.getDrawable(context, resId);
 }
 
 /**
  * 添加多個輪播小點到橫向線性布局
  *
  * @param linearLayout 線性橫向布局
  * @param backgount 小點資源圖標
  * @param number  數量
  * @return 返回小點View集合
  */
 private List<View> addDots(final LinearLayout linearLayout, Drawable backgount, int number) {
  List<View> dots = new ArrayList<>();
  for (int i = 2; i < number; i++) { // 注意這里的 i 從 2 開始,只畫出5個點
 
   int dotId = addDot(linearLayout, backgount);
   dots.add(findViewById(dotId));
 
  }
  return dots;
 }
 
 
}

ic_dot_focused.xml:

<vector android:height="5dp" android:viewportHeight="24.0"
 android:viewportWidth="24.0" android:width="5dp" xmlns:android="http://schemas.android.com/apk/res/android">
 <path android:fillColor="#c8ffffff" android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
</vector>

ic_dot_normal.xml:

<vector android:height="5dp" android:viewportHeight="24.0"
 android:viewportWidth="24.0" android:width="5dp" xmlns:android="http://schemas.android.com/apk/res/android">
 <path android:fillColor="#c8fd8888" android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
</vector>

當然這里主要是實現真正的無限輪播,其中對于 用戶手動滑動圖片時需要暫停輪播沒有做相關處理。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 教你安裝配置Android Studio

    教你安裝配置Android Studio

    對于Android Studio相信大家都不陌生了,作為谷歌推出的安卓開發(fā)工具,做過java的同學應該都了解,下面我們就簡單介紹下這款工具的安裝預配置
    2015-12-12
  • Android local.properties 文件讀取實例詳解

    Android local.properties 文件讀取實例詳解

    這篇文章主要介紹了Android local.properties 文件讀取實例詳解的相關資料,需要的朋友可以參考下
    2017-05-05
  • Android如何使用圓形揭露動畫巧妙地隱藏或顯示View詳解

    Android如何使用圓形揭露動畫巧妙地隱藏或顯示View詳解

    Android開發(fā)中會遇到不少顯示和隱藏的問題,下面這篇文章主要給大家介紹了關于Android如何使用圓形揭露動畫巧妙地隱藏或顯示View的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • 使用PackageManager獲得應用信息實例方法

    使用PackageManager獲得應用信息實例方法

    PackageManager是Android中一個很有用的類,能夠獲取已安裝的應用(包)的信息,如應用名稱、圖標、權限,安裝、刪除應用(包)等
    2013-11-11
  • Android實現底部圖片選擇Dialog

    Android實現底部圖片選擇Dialog

    這篇文章主要為大家詳細介紹了Android實現底部圖片選擇Dialog,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Android設計模式之單例模式詳解

    Android設計模式之單例模式詳解

    這篇文章主要為大家詳細介紹了Android設計模式之單例模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Android中使用Camera類編寫手機拍照App的實例教程

    Android中使用Camera類編寫手機拍照App的實例教程

    這篇文章主要介紹了Android中使用Camera類編寫手機拍照App的實例教程,整理了Camera調用硬件進行拍照的一些常用方法,需要的朋友可以參考下
    2016-04-04
  • 常見android app加固廠商脫殼方法研究

    常見android app加固廠商脫殼方法研究

    這篇文章主要介紹了常見android app加固廠商脫殼方法研究,需要的朋友可以參考下
    2018-01-01
  • Android Studio實現井字游戲

    Android Studio實現井字游戲

    這篇文章主要為大家詳細介紹了Android Studio實現井字游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Android如何從實現到封裝一個MVP詳解

    Android如何從實現到封裝一個MVP詳解

    原生的 MVC 框架遇到大規(guī)模的應用,就會變得代碼難讀,不好維護,無法測試的囧境。因此,Android 開發(fā)方面也有很多對應的框架來解決這些問題。所以這篇文章主要給大家介紹了關于Android如何從實現到封裝一個MVP的相關資料,需要的朋友可以參考下。
    2017-09-09

最新評論