9 ответов:
нет необходимости в таком количестве кода.
вы можете сделать все это без кодирования так много, используя только
viewpagerСtablayout.ваш основной макет:
<RelativeLayout 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.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v4.view.ViewPager> <android.support.design.widget.TabLayout android:id="@+id/tabDots" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabBackground="@drawable/tab_selector" app:tabGravity="center" app:tabIndicatorHeight="0dp"/> </RelativeLayout>подключите элементы пользовательского интерфейса в действии или фрагменте следующим образом:
Java-Кода:
mImageViewPager = (ViewPager) findViewById(R.id.pager); TabLayout tabLayout = (TabLayout) findViewById(R.id.tabDots); tabLayout.setupWithViewPager(mImageViewPager, true);вот и все, вы хорошо идти.
вам нужно будет создайте следующий xml-файл ресурсов в drawable.
tab_indicator_selected.xml
<?xml version="1.0" encoding="utf-8"?> <shape android:innerRadius="0dp" android:shape="ring" android:thickness="4dp" android:useLevel="false"> <solid android:color="@color/colorAccent"/> </shape>tab_indicator_default.xml
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape android:innerRadius="0dp" android:shape="ring" android:thickness="2dp" android:useLevel="false"> <solid android:color="@android:color/darker_gray"/> </shape> </item> </layer-list>tab_selector.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/tab_indicator_selected" android:state_selected="true"/> <item android:drawable="@drawable/tab_indicator_default"/> </selector>
чувствуя себя таким же ленивым, как я? Ну а весь приведенный выше код конвертируется в библиотеку!
использование
добавьте следующее в свой Gradle в:
implementation 'com.chabbal:slidingdotsplash:1.0.2'добавьте следующее в макет действия или фрагмента.
<com.chabbal.slidingdotsplash.SlidingSplashView android:id="@+id/splash" android:layout_width="match_parent" android:layout_height="match_parent" app:imageResources="@array/img_id_arr"/>создать целочисленный массив в
strings.xmlнапример<integer-array name="img_id_arr"> <item>@drawable/img1</item> <item>@drawable/img2</item> <item>@drawable/img3</item> <item>@drawable/img4</item> </integer-array>готово!
дополнительно для прослушивания изменений страницы Используйте
addOnPageChangeListener(listener);Github ссылке.
viewPager.addOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int position) { switch (position) { case 0: img_page1.setImageResource(R.drawable.dot_selected); img_page2.setImageResource(R.drawable.dot); img_page3.setImageResource(R.drawable.dot); img_page4.setImageResource(R.drawable.dot); break; case 1: img_page1.setImageResource(R.drawable.dot); img_page2.setImageResource(R.drawable.dot_selected); img_page3.setImageResource(R.drawable.dot); img_page4.setImageResource(R.drawable.dot); break; case 2: img_page1.setImageResource(R.drawable.dot); img_page2.setImageResource(R.drawable.dot); img_page3.setImageResource(R.drawable.dot_selected); img_page4.setImageResource(R.drawable.dot); break; case 3: img_page1.setImageResource(R.drawable.dot); img_page2.setImageResource(R.drawable.dot); img_page3.setImageResource(R.drawable.dot); img_page4.setImageResource(R.drawable.dot_selected); break; default: break; } } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } });
мое решение ручной работы:
в макете:
<LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/dots" />и в деятельности
private final static int NUM_PAGES = 5; private ViewPager mViewPager; private List<ImageView> dots; @Override protected void onCreate(Bundle savedInstanceState) { // ... addDots(); } public void addDots() { dots = new ArrayList<>(); LinearLayout dotsLayout = (LinearLayout)findViewById(R.id.dots); for(int i = 0; i < NUM_PAGES; i++) { ImageView dot = new ImageView(this); dot.setImageDrawable(getResources().getDrawable(R.drawable.pager_dot_not_selected)); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT ); dotsLayout.addView(dot, params); dots.add(dot); } mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { selectDot(position); } @Override public void onPageScrollStateChanged(int state) { } }); } public void selectDot(int idx) { Resources res = getResources(); for(int i = 0; i < NUM_PAGES; i++) { int drawableId = (i==idx)?(R.drawable.pager_dot_selected):(R.drawable.pager_dot_not_selected); Drawable drawable = res.getDrawable(drawableId); dots.get(i).setImageDrawable(drawable); } }
Я создал библиотеку для удовлетворения потребности в индикаторе страницы в ViewPager. Моя библиотека содержит представление с именем DotIndicator. Чтобы использовать мою библиотеку, добавьте
compile 'com.matthew-tamlin:sliding-intro-screen:3.2.0'в ваш файл сборки gradle.вид можно добавить в макет, добавив следующее:
<com.matthewtamlin.sliding_intro_screen_library.indicators.DotIndicator android:layout_width="wrap_content" android:layout_height="wrap_content" app:numberOfDots=YOUR_INT_HERE app:selectedDotIndex=YOUR_INT_HERE/>приведенный выше код прекрасно воспроизводит функциональность точек на рабочем столе Google Launcher, однако если вы хотите дополнительно настроить его, то следующие атрибуты могут быть добавлено:
app:unselectedDotDiameterиapp:selectedDotDiameterдля установки диаметров точекapp:unselectedDotColorиapp:selectedDotColorчтобы установить цвета точекapp:spacingBetweenDotsизменить расстояние между точкамиapp:dotTransitionDurationчтобы установить время для анимации изменения от малого к большому (и обратно)кроме того, представление может быть создано программно с помощью:
DotIndicator indicator = new DotIndicator(context);существуют методы для изменения свойств, аналогичные атрибут. Чтобы обновить индикатор, чтобы показать другую страницу, как выбрано, просто вызовите метод
indicator.setSelectedItem(int, true)внутриViewPager.OnPageChangeListener.onPageSelected(int).вот пример его использования:
Если вам интересно, библиотека была фактически разработана, чтобы сделать вводные экраны, как показано в приведенном выше gif.
источник Github доступен здесь:https://github.com/MatthewTamlin/SlidingIntroScreen
ViewPagerIndicatorне обновлялся с 2012 года и получил несколько ошибок, которые не были исправлены.Я наконец нашел альтернативу с этой легкой библиотекой, которая отображает хорошие точки для
viewpager, вот ссылка:https://github.com/ongakuer/CircleIndicator
легко реализовать!
вы можете попробовать библиотеку Джейка Уортона -https://github.com/JakeWharton/Android-ViewPagerIndicator
Я думал о публикации более простого решения для вышеуказанной проблемы, и номера индикаторов могут быть динамически изменены только с изменением одного значения переменной
dotCounts=xчто я сделал так.1) Создайте xml-файл в папке drawable для выбранного индикатора страницы с именем "item_selected".
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="true" android:dither="true"> <size android:height="8dp" android:width="8dp"/> <solid android:color="@color/image_item_selected_for_dots"/> </shape>2) Создайте еще один xml-файл для невыбранного индикатора с именем "item_unselected"
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="true" android:dither="true"> <size android:height="8dp" android:width="8dp"/> <solid android:color="@color/image_item_unselected_for_dots"/> </shape>3) Теперь добавить эту часть кода в том месте, где вы хотите, чтобы отобразить индикаторы для бывших ниже
viewPagerв вашем XML-файле макета.<RelativeLayout android:id="@+id/viewPagerIndicator" android:layout_width="match_parent" android:layout_below="@+id/banner_pager" android:layout_height="wrap_content" android:gravity="center"> <LinearLayout android:id="@+id/viewPagerCountDots" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:gravity="center" android:orientation="horizontal" /> </RelativeLayout>4) Добавьте эту функцию поверх вашего файла файла активности, где ваш макет завышен или приведенный выше xml-файл связан с
private int dotsCount=5; //No of tabs or images private ImageView[] dots; LinearLayout linearLayout; private void drawPageSelectionIndicators(int mPosition){ if(linearLayout!=null) { linearLayout.removeAllViews(); } linearLayout=(LinearLayout)findViewById(R.id.viewPagerCountDots); dots = new ImageView[dotsCount]; for (int i = 0; i < dotsCount; i++) { dots[i] = new ImageView(context); if(i==mPosition) dots[i].setImageDrawable(getResources().getDrawable(R.drawable.item_selected)); else dots[i].setImageDrawable(getResources().getDrawable(R.drawable.item_unselected)); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT ); params.setMargins(4, 0, 4, 0); linearLayout.addView(dots[i], params); } }5) Наконец, в вашем методе onCreate добавьте следующий код для ссылки на ваш макет и обработки выбранных страниц позиций
drawPageSelectionIndicators(0); mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { drawPageSelectionIndicators(position); } @Override public void onPageScrollStateChanged(int state) { } });
ниже мое предлагаемое решение.
- поскольку нам нужно показать только некоторые изображения в пейджерах просмотра, поэтому мы избежали громоздкого использования фрагментов.
- реализованы индикаторы просмотра страниц (нижние точки без дополнительной библиотеки или плагина)
- при касании индикаторов просмотра страницы (точек) также происходит навигация по странице.
- пожалуйста, не забудьте добавить свои собственные изображения в ресурсах.
- чувствуете свободно комментировать и улучшать его.
A) Ниже приведен мой activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="schneider.carouseladventure.MainActivity"> <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/viewpager" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <RelativeLayout android:id="@+id/viewPagerIndicator" android:layout_width="match_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" android:layout_marginTop="5dp" android:gravity="center"> <LinearLayout android:id="@+id/viewPagerCountDots" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:gravity="center" android:orientation="horizontal" /> </RelativeLayout> </RelativeLayout>B) pager_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/imageView" /> </LinearLayout>C) MainActivity.java
import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener, View.OnClickListener { int[] mResources = {R.drawable.nature1, R.drawable.nature2, R.drawable.nature3, R.drawable.nature4, R.drawable.nature5, R.drawable.nature6 }; ViewPager mViewPager; private CustomPagerAdapter mAdapter; private LinearLayout pager_indicator; private int dotsCount; private ImageView[] dots; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewPager = (ViewPager) findViewById(R.id.viewpager); pager_indicator = (LinearLayout) findViewById(R.id.viewPagerCountDots); mAdapter = new CustomPagerAdapter(this, mResources); mViewPager.setAdapter(mAdapter); mViewPager.setCurrentItem(0); mViewPager.setOnPageChangeListener(this); setPageViewIndicator(); } private void setPageViewIndicator() { Log.d("###setPageViewIndicator", " : called"); dotsCount = mAdapter.getCount(); dots = new ImageView[dotsCount]; for (int i = 0; i < dotsCount; i++) { dots[i] = new ImageView(this); dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot)); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT ); params.setMargins(4, 0, 4, 0); final int presentPosition = i; dots[presentPosition].setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { mViewPager.setCurrentItem(presentPosition); return true; } }); pager_indicator.addView(dots[i], params); } dots[0].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot)); } @Override public void onClick(View v) { } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { Log.d("###onPageSelected, pos ", String.valueOf(position)); for (int i = 0; i < dotsCount; i++) { dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot)); } dots[position].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot)); if (position + 1 == dotsCount) { } else { } } @Override public void onPageScrollStateChanged(int state) { } }D) CustomPagerAdapter.java
import android.content.Context; import android.support.v4.view.PagerAdapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; public class CustomPagerAdapter extends PagerAdapter { private Context mContext; LayoutInflater mLayoutInflater; private int[] mResources; public CustomPagerAdapter(Context context, int[] resources) { mContext = context; mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mResources = resources; } @Override public Object instantiateItem(ViewGroup container, int position) { View itemView = mLayoutInflater.inflate(R.layout.pager_item,container,false); ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView); imageView.setImageResource(mResources[position]); /* LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(950, 950); imageView.setLayoutParams(layoutParams);*/ container.addView(itemView); return itemView; } @Override public void destroyItem(ViewGroup collection, int position, Object view) { collection.removeView((View) view); } @Override public int getCount() { return mResources.length; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } }E) selecteditem_dot.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="true" android:dither="true"> <size android:height="12dip" android:width="12dip"/> <solid android:color="#7e7e7e"/> </shape>F) nonselecteditem_dot.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="true" android:dither="true"> <size android:height="12dip" android:width="12dip"/> <solid android:color="#d3d3d3"/> </shape>
вот как я это сделал, несколько похоже на решения выше. Просто убедитесь, что вы называете loadDots() метод после загрузки всех изображений.
private int dotsCount; private TextView dotsTextView[]; private void setupAdapter() { adapter = new SomeAdapter(getContext(), images); viewPager.setAdapter(adapter); viewPager.setCurrentItem(0); viewPager.addOnPageChangeListener(viewPagerPageChangeListener); } private final ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {} @Override public void onPageSelected(int position) { for (int i = 0; i < dotsCount; i++) dotsTextView[i].setTextColor(Color.GRAY); dotsTextView[position].setTextColor(Color.WHITE); } @Override public void onPageScrollStateChanged(int state) {} }; protected void loadDots() { dotsCount = adapter.getCount(); dotsTextView = new TextView[dotsCount]; for (int i = 0; i < dotsCount; i++) { dotsTextView[i] = new TextView(getContext()); dotsTextView[i].setText(R.string.dot); dotsTextView[i].setTextSize(45); dotsTextView[i].setTypeface(null, Typeface.BOLD); dotsTextView[i].setTextColor(android.graphics.Color.GRAY); mDotsLayout.addView(dotsTextView[i]); } dotsTextView[0].setTextColor(Color.WHITE); } XML <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="180dp" android:background="#00000000"/> <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/introImageView" android:layout_width="match_parent" android:layout_height="match_parent"/> <LinearLayout android:id="@+id/image_count" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00000000" android:gravity="center|bottom" android:orientation="horizontal"/> </FrameLayout>






Comments