Tôi muốn thêm 3 dấu chấm dưới cùng vào ViewPager của mình, như thế này.
Tôi sử dụng FragmentActivity và hỗ trợ thư viện ViewPager.
Tôi muốn thêm 3 dấu chấm dưới cùng vào ViewPager của mình, như thế này.
Tôi sử dụng FragmentActivity và hỗ trợ thư viện ViewPager.
Câu trả lời:
Không cần nhiều mã đó.
Bạn có thể làm tất cả những thứ này mà không cần mã hóa nhiều bằng cách chỉ sử dụng viewpager
với tablayout
.
Bố cục chính của bạn:
<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>
Kết nối các thành phần UI của bạn không hoạt động hoặc phân đoạn như sau:
Mã Java:
mImageViewPager = (ViewPager) findViewById(R.id.pager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabDots);
tabLayout.setupWithViewPager(mImageViewPager, true);
Đó là nó, bạn tốt để đi.
Bạn sẽ cần tạo tệp tài nguyên xml sau trong thư mục drawable .
tab_indicator_selected.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
android:innerRadius="0dp"
android:shape="oval"
android:thickness="4dp"
android:useLevel="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorAccent"/>
</shape>
tab_indicator_default.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="oval"
android:thickness="2dp"
android:useLevel="false">
<solid android:color="@android:color/darker_gray"/>
</shape>
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>
Cảm thấy lười biếng như tôi? Vâng, tất cả các mã trên được chuyển đổi thành một thư viện!
Cách sử dụng
Thêm phần sau vào lớp của bạn:
implementation 'com.chabbal:slidingdotsplash:1.0.2'
Thêm phần sau vào bố cục Hoạt động hoặc Đoạn của bạn.
<com.chabbal.slidingdotsplash.SlidingSplashView
android:id="@+id/splash"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:imageResources="@array/img_id_arr"/>
Tạo một mảng số nguyên trong strings.xml
ví dụ
<integer-array name="img_id_arr">
<item>@drawable/img1</item>
<item>@drawable/img2</item>
<item>@drawable/img3</item>
<item>@drawable/img4</item>
</integer-array>
Làm xong!
Thêm để nghe thay đổi trang sử dụng liên kếtaddOnPageChangeListener(listener);
Github .
com.google.android.material.tabs.TabLayout
trong các Phiên bản mới hơn
ring
. Có vẻ như chiếc nhẫn cũng được sử dụng trong thư viện slidedotsplash thay vì hình bầu dục.
Giải pháp thủ công của tôi:
Trong cách bố trí:
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/dots"
/>
Và trong Hoạt động
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);
}
}
Layout
chỉ để đặt một dấu chấm? Sử dụng View
thay thế.
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) {
}
});
setOnPageChangedListener()
không tán thành !! Sử dụng addOnPageChangedListener()
ngay bây giờ.
Tôi đã tạo một thư viện để giải quyết nhu cầu về chỉ báo trang trong ViewPager. Thư viện của tôi chứa Chế độ xem có tên là DotIndicator. Để sử dụng thư viện của tôi, hãy thêm compile 'com.matthew-tamlin:sliding-intro-screen:3.2.0'
vào tập tin xây dựng lớp của bạn.
Chế độ xem có thể được thêm vào bố cục của bạn bằng cách thêm vào như sau:
<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/>
Đoạn mã trên sao chép hoàn hảo chức năng của các dấu chấm trên màn hình chính của Google Launcher, tuy nhiên nếu bạn muốn tùy chỉnh thêm thì có thể thêm các thuộc tính sau:
app:unselectedDotDiameter
và app:selectedDotDiameter
để đặt đường kính của các chấmapp:unselectedDotColor
và app:selectedDotColor
để đặt màu của các chấmapp:spacingBetweenDots
để thay đổi khoảng cách giữa các dấu chấmapp:dotTransitionDuration
để đặt thời gian cho hoạt ảnh thay đổi từ nhỏ sang lớn (và trở lại)Ngoài ra, chế độ xem có thể được tạo theo chương trình bằng cách sử dụng:
DotIndicator indicator = new DotIndicator(context);
Các phương thức tồn tại để sửa đổi các thuộc tính, tương tự như các thuộc tính. Để cập nhật chỉ báo để hiển thị một trang khác như đã chọn, chỉ cần gọi phương thức indicator.setSelectedItem(int, true)
từ bên trong ViewPager.OnPageChangeListener.onPageSelected(int)
.
Đây là một ví dụ về nó được sử dụng:
Nếu bạn quan tâm, thư viện thực sự được thiết kế để tạo các màn hình giới thiệu giống như màn hình hiển thị trong gif ở trên.
Nguồn Github có sẵn tại đây: https://github.com/MatthewTamlin/SlidingIntroScreen
int getNumberOfItems()
và void setNumberOfItems()
. Thay vì bắt ngoại lệ, bạn có thể làm một cái gì đó như gist.github.com/MatthewTamlin/761c7338d271af29526edc7859480aef này .
ViewPagerIndicator
đã không được cập nhật từ năm 2012 và có một số lỗi không bao giờ được sửa.
Cuối cùng tôi đã tìm thấy một sự thay thế với thư viện ánh sáng này hiển thị các chấm đẹp cho viewpager
, đây là liên kết:
https://github.com/ongakuer/CircleTheicator
Dễ để thực hiện!
Tôi đã nghĩ đến việc đăng một giải pháp đơn giản hơn cho vấn đề trên và các số chỉ báo có thể được thay đổi linh hoạt chỉ bằng cách thay đổi một giá trị biến dotCounts=x
mà tôi đã làm như thế này.
1) Tạo tệp xml trong thư mục có thể vẽ cho chỉ báo được chọn trang có tên "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) Tạo thêm một tệp xml cho chỉ báo chưa được chọn có tên "item_unelected"
<?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) Bây giờ thêm thêm phần mã này vào nơi bạn muốn hiển thị các chỉ số cho ex bên dưới viewPager
trong tệp XML Bố cục của bạn.
<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) Thêm chức năng này vào đầu tệp tệp hoạt động của bạn nơi bố cục của bạn bị thổi phồng hoặc tệp xml ở trên có liên quan đến
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) Cuối cùng, trong phương thức onCreate của bạn, thêm đoạn mã sau để tham chiếu bố cục của bạn và xử lý các vị trí được chọn trang
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) {
}
});
Bạn có thể dùng thử thư viện của Jake Wharton - https://github.com/JakeWharton/Android-ViewPagerTheicator
Sau đây là giải pháp đề xuất của tôi.
A) Sau đây là Activity_main.xml của tôi
<?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) CustomPagerAd Module.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) chọnitem_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>
Nếu bất cứ ai muốn xây dựng một viewPager
hình thu nhỏ làm chỉ số, sử dụng thư viện này có thể là một tùy chọn:
ThumbTheicator cho viewPager hoạt động với các liên kết hình ảnh dưới dạng tài nguyên.
Đây là cách tôi đã làm điều này, hơi giống với các giải pháp ở trên. Chỉ cần đảm bảo bạn gọi phương thức loadDots () sau khi tất cả hình ảnh được tải xuống .
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>