วิธีการใช้งาน Android Pull-to-Refresh


432

ในแอปพลิเคชัน Android เช่น Twitter (แอปอย่างเป็นทางการ) เมื่อคุณพบ ListView คุณสามารถดึงมันลงมา (และมันจะเด้งกลับมาเมื่อวางจำหน่าย) เพื่อรีเฟรชเนื้อหา

ฉันสงสัยว่าอะไรคือวิธีที่ดีที่สุดในความคิดเห็นของคุณ

ความเป็นไปได้บางอย่างที่ฉันคิดได้:

  1. รายการที่อยู่ด้านบนของ ListView - แต่ฉันไม่คิดว่าการเลื่อนกลับไปที่ตำแหน่งของรายการ 1 (อิงกับ 0) พร้อมภาพเคลื่อนไหวบน ListView นั้นเป็นงานง่าย
  2. อีกมุมมองหนึ่งภายนอก ListView - แต่ฉันต้องระวังการย้ายตำแหน่ง ListView ลงเมื่อมันถูกดึงออกมาและฉันไม่แน่ใจว่าเราสามารถตรวจพบว่าการลากไปแตะที่ ListView ยังคงเลื่อนรายการใน ListView จริง ๆ หรือไม่

คำแนะนำใด ๆ

ป.ล. ฉันสงสัยว่าเมื่อซอร์สโค้ดแอป Twitter อย่างเป็นทางการเปิดตัวแล้ว มีการกล่าวถึงว่าจะมีการเปิดตัว แต่ 6 เดือนผ่านไปแล้วและเราไม่เคยได้ยินเรื่องนี้มาก่อน


ฟังก์ชันนี้สามารถนำไปใช้ใน TableLayout ที่สร้างขึ้นแบบไดนามิกหรือไม่ กรุณาช่วย .....
Arun Badole

github.com/fruitranger/PulltorefreshListViewเป็นอีกหนึ่งการติดตั้งของฉัน การสนับสนุนที่ราบรื่นและหลายสัมผัส
Changwei Yao

6
เกี่ยวข้อง: “ Pull-to-refresh”: รูปแบบการต่อต้าน UI บน Androidเป็นบทความที่โต้แย้งว่า UI นี้ไม่ใช่สิ่งที่ควรใช้บน Android และจุดประกายการอภิปรายจำนวนมากเกี่ยวกับความเหมาะสมของมัน
blahdiblah

29
บางคนควรแจ้งให้ Google ทราบเนื่องจาก Gmail สำหรับ Android เวอร์ชันล่าสุดใช้ "รูปแบบการต่อต้าน" นี้
Nick

4
การดึงเพื่อรีเฟรชคือ (และมีมาพักนานแล้ว) รูปแบบที่ใช้มาตรฐานใน iOS และ Android และเป็นเรื่องธรรมดามากดังนั้นการอภิปรายรูปแบบต่อต้านนี้จึงล้าสมัย ผู้ใช้จะคาดหวังว่าจะเห็นมันและประพฤติตนเช่นนั้น
Martin Marconcini

คำตอบ:


310

ในที่สุด Google ได้เปิดตัวไลบรารี่รีเฟรชเวอร์ชั่นทางการ!

มันถูกเรียกว่าSwipeRefreshLayoutภายในห้องสมุดสนับสนุนและเอกสารอยู่ที่นี่ :

  1. เพิ่มSwipeRefreshLayoutเป็นพาเรนต์ของมุมมองซึ่งจะถือว่าเป็นการดึงเพื่อรีเฟรชโครงร่าง (ผมเอาListViewเป็นตัวอย่างก็สามารถใด ๆViewเช่นLinearLayout, ScrollViewฯลฯ )

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/pullToRefresh"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </android.support.v4.widget.SwipeRefreshLayout>
  2. เพิ่มผู้ฟังให้กับชั้นเรียนของคุณ

    protected void onCreate(Bundle savedInstanceState) {
        final SwipeRefreshLayout pullToRefresh = findViewById(R.id.pullToRefresh);
        pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                refreshData(); // your code
                pullToRefresh.setRefreshing(false);
            }
        });
    }

นอกจากนี้คุณยังสามารถโทรpullToRefresh.setRefreshing(true/false);ตามความต้องการของคุณ

UPDATE

ไลบรารีสนับสนุน Android ถูกเลิกใช้แล้วและถูกแทนที่ด้วย AndroidX เชื่อมโยงไปยังห้องสมุดใหม่ที่สามารถพบได้ที่นี่

นอกจากนี้คุณต้องเพิ่มการพึ่งพาต่อไปนี้ในโครงการของคุณ:

implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'

หรือ

คุณสามารถไปที่ Refactor >> โยกย้ายไปยัง AndroidX และ Android Studio จะจัดการการพึ่งพาสำหรับคุณ


3
ฉันสามารถใช้ ProgressBar แทน Color Scheme บน SwipeRefreshLayout ได้อย่างไร
pablobaldez

54
1 เมษายน '14 - และนั่นไม่ใช่เรื่องตลก
aeracode


80

ฉันได้ทำให้ความพยายามที่จะใช้ดึงไปยังส่วนการฟื้นฟูก็ห่างไกลจากความสมบูรณ์แต่แสดงให้เห็นถึงการดำเนินงานที่เป็นไปได้https://github.com/johannilsson/android-pulltorefresh

ตรรกะหลักจะดำเนินการในที่ขยายPullToRefreshListView ภายในจะควบคุมการเลื่อนของมุมมองส่วนหัวโดยใช้(ระดับ API 8) วิดเจ็ตได้รับการอัพเดตพร้อมรองรับ 1.5 และใหม่กว่าโปรดอ่าน README สำหรับการรองรับ 1.5ListViewsmoothScrollBy

ในเลย์เอาต์ของคุณคุณเพิ่มมันแบบนี้

<com.markupartist.android.widget.PullToRefreshListView
    android:id="@+id/android:list"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    />

3
สวัสดีโจฮานฉันดาวน์โหลดโค้ดตัวอย่างของคุณแล้ว มันทำงานในอุปกรณ์ android 2.2 แต่ไม่สามารถใช้งานได้ในอุปกรณ์ 2.1 ฉันคิดว่าเพราะใช้วิธีsmoothScrollByซึ่งใช้ได้เฉพาะใน 2.2 หรือใหม่กว่านั้นถูกต้องหรือไม่ และคุณมีความคิดที่จะใช้เอฟเฟกต์นี้เป็น 2.1 หรือเวอร์ชันก่อนหน้านี้หรือไม่? ขอบคุณ

ใช่ถูกต้องตามที่ระบุไว้ในคำตอบ smoothScrollBy ได้รับการแนะนำใน API ระดับ 8 (2.2) ฉันยังไม่พบวิธีที่เหมาะสมในการนำไปใช้กับเวอร์ชันอื่น ๆ แต่มันคิดว่ามันควรจะเป็นไปได้ที่จะนำพอร์ตไปใช้กับ smoothScrollBy แต่ฉันเดาว่าการอภิปรายควรจะถูกเก็บไว้ที่ไซต์โครงการ
Johan Berg Nilsson

มันมีจุดประสงค์ที่ id คือ @ + id / android: ไม่ใช่หรือไม่ใช่ @android: id / list มันดูแปลกใช่ไหม โครงการโยนข้อผิดพลาดเงินเฟ้อที่นี่ที่ด้านข้างของฉันฉันกำลังตรวจสอบในที่ ...
Mathias Conradt

12
นี้เป็นห้องสมุดที่ดีที่สุดสำหรับการดึงเพื่อฟื้นฟูฉันได้พบ .. github.com/chrisbanes/Android-PullToRefresh มันทำงานร่วมกับ ListViews, GridViews และ Webviews มี Pull up เพื่อรีเฟรชรูปแบบที่ใช้
rOrlig

1
ฉันจะเพิ่มโครงการลงในโฟลเดอร์ไลบรารีขณะทำงานกับ Intellij Idea ได้อย่างไร ใครช่วยฉันได้บ้าง
มุสตาฟากัวเวน

55

ฉันได้ติดตั้งไลบรารี PullToRefresh ที่แข็งแกร่งใช้งานง่ายและปรับแต่งได้สูงสำหรับ Android คุณสามารถแทนที่ ListView ของคุณด้วย PullToRefreshListView ตามที่อธิบายไว้ในเอกสารประกอบในหน้าโครงการ

https://github.com/erikwt/PullToRefresh-ListView


ฉันพยายามใช้งานทั้งหมดที่ระบุไว้ที่นี่และของคุณดีที่สุดในแง่ของการดึงเรียบ / บริสุทธิ์ / เรียบเพื่อฟื้นฟูการใช้งาน (ไม่มีการแตะเพื่อฟื้นฟูความแปลกประหลาดเช่น Johan) ขอบคุณ!
Gady

1
สิ่งนี้สามารถแทนที่ ListView มาตรฐานเพื่อทำงานกับ ListActivity, ListFragment และอื่น ๆ ได้หรือไม่?
davidcesarino

ใช่เพียงแค่ให้ PullToRefreshList ดูรหัสที่ถูกต้อง ใน XML: android: id = "@ android: id / list"
Erik

1
มันยอดเยี่ยมมาก! google นำมาให้ฉันที่นี่และดูตัวอย่างสิ่งที่คุณเห็นจะนำไปใช้งานได้ง่ายที่สุด ไชโยและขอขอบคุณคุณ!
Evan R.

องค์ประกอบที่ออกแบบมาอย่างสมเหตุสมผลดีและเรียบง่าย นี่ควรเป็นคำตอบที่ยอมรับได้อย่างแน่นอน
อดัม

42

วิธีที่ง่ายที่สุดที่ฉันคิดว่ามีให้โดยห้องสมุดสนับสนุน android:

android.support.v4.widget.SwipeRefreshLayout;

เมื่อนำเข้าแล้วคุณสามารถกำหนดเค้าโครงได้ดังนี้

  <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/refresh"
        android:layout_height="match_parent"
        android:layout_width="match_parent">
    <android.support.v7.widget.RecyclerView
        xmlns:recycler_view="http://schemas.android.com/apk/res-auto"
        android:id="@android:id/list"
        android:theme="@style/Theme.AppCompat.Light"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/button_material_light"
        >

    </android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>

ฉันคิดว่าคุณใช้มุมมองรีไซเคิลจากรายการมุมมอง อย่างไรก็ตาม listview ยังคงใช้งานได้ดังนั้นคุณเพียงแค่เปลี่ยน recyclerview ด้วย listview และอัปเดตข้อมูลอ้างอิงในโค้ด java (Fragment)

ในแฟรกเมนต์กิจกรรมของคุณคุณต้องใช้อินเตอร์เฟสSwipeRefreshLayout.OnRefreshListener: i, e

public class MySwipeFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener{
private SwipeRefreshLayout swipeRefreshLayout;

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_item, container, false);
        swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh);
        swipeRefreshLayout.setOnRefreshListener(this);
}


 @Override
  public void onRefresh(){
     swipeRefreshLayout.setRefreshing(true);
     refreshList();
  }
  refreshList(){
    //do processing to get new data and set your listview's adapter, maybe  reinitialise the loaders you may be using or so
   //when your data has finished loading, cset the refresh state of the view to false
   swipeRefreshLayout.setRefreshing(false);

   }
}

หวังว่านี่จะช่วยมวลชน


มันใช้งานได้ดี แต่สิ่งหนึ่งที่เกี่ยวกับsetRefreshing: "อย่าเรียกนี้เมื่อรีเฟรชถูกเรียกโดยท่าทางรูด" ตามที่อธิบายในdeveloper.android.com/reference/android/support/v4/widget/...
gabriel14

เยี่ยมมาก! ขอบคุณ
technik

22

ในลิงค์นี้คุณจะพบกับทางแยกที่โด่งดัง PullToRefreshมุมมองที่มีซึ่งมีการนำไปใช้งานใหม่ที่น่าสนใจเช่นPullTorRefreshWebViewหรือPullToRefreshGridViewความเป็นไปได้ที่จะเพิ่มส่วนที่PullToRefreshอยู่ด้านล่างของรายการ

https://github.com/chrisbanes/Android-PullToRefresh

และสิ่งที่ดีที่สุดคือมันทำงานได้อย่างสมบูรณ์แบบใน Android 4.1 (ปกติPullToRefreshไม่ทำงาน)


3
ความคิดเห็นขนาดใหญ่ที่ด้านบนของ readme บ่งชี้ว่า: โครงการนี้ไม่มีการซ่อมอีกต่อไป อย่างไรก็ตาม lib นี้เป็นสิ่งที่ดีที่สุดที่ฉันเคยเห็น! การทำงานที่ดี!
มิลตัน

3
เพียงเพราะมันไม่ได้รับการบำรุงรักษาอีกต่อไปไม่ได้หมายความว่ามันไม่ดี ยังคงใช้มันสำหรับทุกดึงของฉันที่จะตอบสนองความต้องการการฟื้นฟู :)
Muz

18

ฉันมีวิธีที่ง่ายมากในการทำเช่นนี้ แต่ตอนนี้แน่ใจว่าเป็นวิธีที่เข้าใจผิดได้มีรหัสของฉัน PullDownListView.java

package com.myproject.widgets;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;

/**
 * @author Pushpan
 * @date Nov 27, 2012
 **/
public class PullDownListView extends ListView implements OnScrollListener {

    private ListViewTouchEventListener mTouchListener;
    private boolean pulledDown;

    public PullDownListView(Context context) {
        super(context);
        init();
    }

    public PullDownListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public PullDownListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        setOnScrollListener(this);
    }

    private float lastY;

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            lastY = ev.getRawY();
        } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
            float newY = ev.getRawY();
            setPulledDown((newY - lastY) > 0);
            postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (isPulledDown()) {
                        if (mTouchListener != null) {
                            mTouchListener.onListViewPulledDown();
                            setPulledDown(false);
                        }
                    }
                }
            }, 400);
            lastY = newY;
        } else if (ev.getAction() == MotionEvent.ACTION_UP) {
            lastY = 0;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        setPulledDown(false);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    public interface ListViewTouchEventListener {
        public void onListViewPulledDown();
    }

    public void setListViewTouchListener(
            ListViewTouchEventListener touchListener) {
        this.mTouchListener = touchListener;
    }

    public ListViewTouchEventListener getListViewTouchListener() {
        return mTouchListener;
    }

    public boolean isPulledDown() {
        return pulledDown;
    }

    public void setPulledDown(boolean pulledDown) {
        this.pulledDown = pulledDown;
    }
}

คุณเพียงแค่ต้องใช้ ListViewTouchEventListener ในกิจกรรมที่คุณต้องการใช้ ListView นี้และตั้งค่าฟัง

ฉันใช้มันใน PullDownListViewActivity

package com.myproject.activities;

import android.app.Activity;
import android.os.Bundle;

/**
 * @author Pushpan
 *
 */
public class PullDownListViewActivity extends Activity implements ListViewTouchEventListener {

    private PullDownListView listView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        listView = new PullDownListView(this);
        setContentView(listView);
        listView.setListViewTouchListener(this);

        //setItems in listview
    }

    public void onListViewPulledDown(){
        Log.("PullDownListViewActivity", "ListView pulled down");
    }
}

มันเหมาะกับฉัน :)


18

ในการติดตั้ง android Pull-to-Refresh ให้ลองใช้โค้ดนี้

<android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/pullToRefresh"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</android.support.v4.widget.SwipeRefreshLayout>

ชั้นเรียนกิจกรรม:

ListView lv = (ListView) findViewById(R.id.lv);
SwipeRefreshLayout pullToRefresh = (SwipeRefreshLayout) findViewById(R.id.pullToRefresh);


lv.setAdapter(mAdapter);

pullToRefresh.setOnRefreshListener(new OnRefreshListener() {

        @Override
        public void onRefresh() {
            // TODO Auto-generated method stub

            refreshContent();

        }
    });



private void refreshContent(){ 

     new Handler().postDelayed(new Runnable() {
            @Override public void run() {
                pullToRefresh.setRefreshing(false);
            }
        }, 5000);

 }

1
Thanks.it ช่วยฉันได้จริงๆ
Arpan Sharma

9

ไม่มีใครพูดถึง "ดึงเพื่อรีเฟรช" รูปแบบใหม่ซึ่งจะปรากฏที่ด้านบนของแถบการกระทำเช่นในแอปพลิเคชัน Google Now หรือ Gmail

มีไลบรารีActionBar-PullToRefreshซึ่งทำงานเหมือนกันทุกประการ


7

โปรดทราบว่ามีปัญหาเกี่ยวกับ UX ที่ต้องพิจารณาเมื่อใช้งานบน Android และ WP

"ตัวบ่งชี้ที่ดีว่าทำไมนักออกแบบ / นักพัฒนาไม่ควรใช้ pull-to-refresh ในแอพ iOS ที่มีสไตล์เป็นวิธีที่ Google และทีมของพวกเขาไม่เคยใช้ pull-to-refresh บน Android ในขณะที่พวกเขาใช้มันใน iOS"

https://plus.google.com/109453683460749241197/posts/eqYxXR8L4eb


3
ฉันรู้ว่านี่อายุเกินหนึ่งปีแล้ว แต่แอป Gmail ใช้ pull-to-refresh อย่างไรก็ตามมันไม่เหมือนกันในแง่ของ UI รายการไม่เลื่อนลง แต่มุมมองใหม่จะแสดงที่ด้านบนของหน้าจอ
ashishduh

4

หากคุณไม่ต้องการให้โปรแกรมของคุณดูเหมือนโปรแกรม iPhone ที่ติดตั้งลงใน Android แล้วลองมองหารูปลักษณ์และความรู้สึกของชาวพื้นเมืองและทำสิ่งที่คล้ายกับ Gingerbread:

ข้อความแสดงแทน


2
@Rob: ฉันหมายถึงมีเงาสีส้มที่ด้านบนของรายการเมื่อคุณ overpull แทนที่จะมีรายการเด้งกลับเหมือนใน iPhone สิ่งนี้มีความหมายว่าเป็นความคิดเห็น (ไม่ใช่คำตอบ) แต่ความคิดเห็นไม่สามารถมีภาพได้
โกหก,

อ๊ะขอโทษความคิดที่ยอดเยี่ยม ฉันยังไม่ได้เล่นกับขนมปังขิงเลยยังไม่เห็นผล ยังคงรอ google เพื่อย้อนไปหนึ่ง Nexus
Rob

9
ฉันมี Gingerbread และแสงสีส้มใช้งานได้ดีเมื่อรายการคงที่ แต่ pull-down-refresh เป็น mecanism UI ที่ยอดเยี่ยมในการรีเฟรชรายการแบบไดนามิก แม้ว่าจะเป็นที่แพร่หลายในโลก iOS มันเป็นเคล็ดลับ UI ที่ไม่รู้สึกแปลกในระบบนิเวศ Android ฉันขอแนะนำให้คุณลองใช้งานในแอพ Twitter อย่างเป็นทางการ :)
Thierry-Dimitri Roy

พฤติกรรมดั้งเดิมที่นี่คือการระบุว่าคุณมาถึงจุดสิ้นสุดของรายการแล้ว การดำเนินการนี้และการรีเฟรชนั้นไม่เหมือนกันกับที่คุณไม่ได้ทำในสิ่งที่แพลตฟอร์มทำ ซึ่งหมายความว่าคุณมีแนวโน้มที่จะแปลกใจผู้ใช้ แน่นอนว่าฉันจะไม่คาดหวังและไม่ต้องการการรีเฟรชเพียงเพราะฉันไปถึงจุดสิ้นสุดของรายการ ดึงลงเพื่อรีเฟรชมากขึ้นใช้งานง่ายและชัดเจนมากขึ้น และด้วยแอพ twitter ดั้งเดิมที่ใช้ฉันคิดว่ามันยุติธรรมที่จะพูดว่ามันเป็นแนวคิด UI ที่คนจำนวนมากคุ้นเคย
steprobe

4

ฉันได้เขียนองค์ประกอบดึงเพื่อรีเฟรชที่นี่: https://github.com/guillep/PullToRefresh มันทำงานได้ถ้ารายการไม่มีรายการและฉันได้ทำการทดสอบบน> = 1.6 โทรศัพท์ android

ข้อเสนอแนะหรือการปรับปรุงใด ๆ ที่ชื่นชม :)



1

วิธีรับ Lollipop Pull-To Refresh ล่าสุด:

  1. ดาวน์โหลดไลบรารีสนับสนุน Lollipop SDK และ Extras / Android ล่าสุด
  2. กำหนดเป้าหมายการสร้างโครงการเป็น Android 5.0 (มิฉะนั้นแพ็คเกจสนับสนุนอาจมีข้อผิดพลาดเกี่ยวกับทรัพยากร)
  3. อัปเดต libs / android-support-v4.jar เป็นเวอร์ชัน 21
  4. ใช้เครื่องหมายandroid.support.v4.widget.SwipeRefreshLayoutบวกandroid.support.v4.widget.SwipeRefreshLayout.OnRefreshListener

คู่มือรายละเอียดสามารถพบได้ที่นี่: http://antonioleiva.com/swiperefreshlayout/

Plus สำหรับ ListView ฉันแนะนำให้อ่านcanChildScrollUp()ในความคิดเห็น;)


บวกหนึ่งสำหรับการกล่าวถึง canChildScrollUp () สำคัญมาก!
Petro

1

ที่น่าสนใจมากดึงเพื่อรีเฟรชโดยYalantis Gif สำหรับ iOS แต่คุณสามารถตรวจสอบได้ :)

<com.yalantis.pulltorefresh.library.PullToRefreshView
android:id="@+id/pull_to_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
    android:id="@+id/list_view"
    android:divider="@null"
    android:dividerHeight="0dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />


0

ก่อนอื่นเราควรรู้ว่าอะไรคือ Pull เพื่อรีเฟรชเลย์เอาต์ใน android เราสามารถเรียก pull เพื่อรีเฟรชใน android โดยใช้คำสั่ง swipe-to-refresh เมื่อคุณปัดหน้าจอจากบนลงล่างจะทำการกระทำบางอย่างตาม setOnRefreshListener

นี่คือบทแนะนำที่แสดงให้เห็นถึงวิธีการใช้งาน android pull เพื่อรีเฟรช ฉันหวังว่านี่จะช่วยได้.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.