it-swarm-eu.dev

Horizontální ListView v Androidu?

Je možné provést ListView vodorovně? Udělal jsem to pomocí Galerie zobrazení, ale vybraná položka se automaticky dostane do středu obrazovky. Nechci vybranou položku na stejném místě, na které jsem kliknul. Jak mohu tento problém napravit? Mým nápadem bylo nastavit ListView s vodorovným svitkem. Podělte se o svůj nápad?

201
Praveen

Podle dokumentace systému Android RecyclerView je nový způsob uspořádání položek v seznamu a zobrazení vodorovně

Výhody:

  1. Vzhledem k tomu, že pomocí Recyclerview Adapter, ViewHolder vzor je Automaticky implementován
  2. Animace se snadno provádí
  3. Mnoho dalších funkcí

Více informací o RecyclerView:

  1. grokkingandroid.com
  2. antonioleiva.com

Vzorek:

přežívajícíwithandroid.com

Stačí přidat níže uvedený blok, aby se ListView změnilo na horizontální ze svislé polohy

Kódový fragment

LinearLayoutManager layoutManager= new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, false);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(layoutManager);
110
Devrath

Paul se neobtěžuje opravit chyby své knihovny nebo přijímat opravy uživatelů. Proto navrhuji jinou knihovnu, která má podobnou funkčnost: 

https://github.com/sephiroth74/HorizontalVariableListView

Update: dne 24.7.2013 autor (sephiroth74) vydal zcela přepsanou verzi založenou na kódu Android 4.2.2 ListView. Musím říct, že nemá všechny chyby, které předchozí verze měla a funguje skvěle!

60
Malachiasz

@Paul odpovědět odkazy na skvělé řešení, ale kód neumožňuje použít onClickListeners na položky děti (funkce zpětného volání nejsou nikdy volány). Chvíli jsem bojoval, abych našel řešení a rozhodl jsem se, že sem pošlu to, co potřebujete v tomto kódu upravit (v případě, že ho někdo potřebuje).

Namísto přepsání dispatchTouchEvent přepsání onTouchEvent. Použijte stejný kód dispatchTouchEvent a vymažte metodu (můžete si přečíst rozdíl mezi těmito dvěma zde http://developer.Android.com/guide/topics/ui/ui-events.html#EventHandlers )

@Override
public boolean onTouchEvent(MotionEvent event) {
    boolean handled = mGesture.onTouchEvent(event);
    return handled;
}

Pak přidejte následující kód, který se rozhodne krást událost z položky děti a dát ji do našeho onTouchEvent, nebo nechat být zpracován nimi.

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    switch( ev.getActionMasked() ){
        case MotionEvent.ACTION_DOWN:
             mInitialX = ev.getX();
             mInitialY = ev.getY();             
             return false;
        case MotionEvent.ACTION_MOVE:
             float deltaX = Math.abs(ev.getX() - mInitialX);
             float deltaY = Math.abs(ev.getY() - mInitialY);
             return ( deltaX > 5 || deltaY > 5 );
        default:
             return super.onInterceptTouchEvent(ev);
    }
}

Nakonec nezapomeňte deklarovat proměnné ve své třídě:

private float mInitialX;
private float mInitialY;
28
Xavi Gil

Vzhledem k tomu, Google zavedl Android Support Library v7 21.0.0, můžete použít RecyclerView k posouvání položek vodorovně. Widget RecyclerView je pokročilejší a flexibilnější verze ListView.

Chcete-li použít RecyclerView, stačí přidat závislost:

com.Android.support:recyclerview-v7:23.0.1

Zde je ukázka:

public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager(layoutManager);

        MyAdapter adapter = new MyAdapter(myDataset);
        recyclerView.setAdapter(adapter);
    }
}

Více informací o RecyclerView:

23
klimat

To je trochu (velmi) pozdě, ale já to vysílám v případě, že někdo přijde později.

Knihovna podpory od náhledu Android L má RecyclerView , která dělá přesně to, co chcete.

Právě teď jej můžete získat pouze prostřednictvím L náhled SDK a musíte nastavit minSdk na L. Všechny potřebné soubory však můžete kopírovat do svého projektu a použít je tak dlouho, dokud L nebude oficiálně vyřazen.

Můžete si stáhnout náhled dokumentů zde .

Upozornění: Rozhraní API pro zobrazení Recycler View se může změnit a může mít chyby.

Aktualizováno

Zdrojový kód pro horizontální zobrazení seznamu je:

LinearLayoutManager layoutManager
    = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);

RecyclerView myList = findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);
21
Abhay Buch

Stáhnout soubor jar z zde

nyní ji vložte do složky libs, klikněte na ni pravým tlačítkem myši a vyberte možnost Přidat jako knihovnu 

nyní v main.xml vložte tento kód

 <com.devsmart.Android.ui.HorizontalListView
    Android:id="@+id/hlistview"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    />

nyní ve třídě Aktivita, chcete-li Horizontal Listview s obrázky, vložte tento kód

  HorizontalListView hListView = (HorizontalListView) findViewById(R.id.hlistview);
    hListView.setAdapter(new HAdapter(this));


 private class HAdapter extends BaseAdapter {

    LayoutInflater inflater;

    public HAdapter(Context context) {
        inflater = LayoutInflater.from(context);

    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return Const.template.length;
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        HViewHolder holder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.listinflate, null);
            holder = new HViewHolder();
            convertView.setTag(holder);

        } else {
            holder = (HViewHolder) convertView.getTag();
        }
        holder.img = (ImageView) convertView.findViewById(R.id.image);
        holder.img.setImageResource(Const.template[position]);
        return convertView;
    }

}

class HViewHolder {
    ImageView img;
}
17
Siddhpura Amit

Je to vlastně velmi jednoduché: Jednoduše Otočte zobrazení seznamu tak, aby ležel na jeho straně

mlistView.setRotation(-90);

Poté, co se děti nafouknou, by měly být uvnitř metody getView. otočíte děti tak, abyste se postavili rovně: 

 mylistViewchild.setRotation(90);

Edit: Pokud váš ListView po otočení nezapadá správně, umístěte ListView do tohoto RotateLayout takto:

 <com.github.rongi.rotate_layout.layout.RotateLayout
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    app:angle="90"> <!-- Specify rotate angle here -->

    <ListView
       Android:layout_width="match_parent"
       Android:layout_height="match_parent">
    </ListView>
</com.github.rongi.rotate_layout.layout.RotateLayout>
12
kc ochibili

Moje řešení je jednoduše použít ViewPager widget. Není uzamčeno na střed jako Gallery a má vestavěné funkce pro zobrazení recyklace (jako ListView). Podobný přístup můžete vidět v aplikaci Google Play, kdykoli se zabýváte horizontálně posouvatelnými seznamy.

Musíte pouze rozšířit PagerAdapter a provést několik vylepšení:

public class MyPagerAdapter extends PagerAdapter {

    private Context mContext;

    public MyPagerAdapter(Context context) {
        this.mContext = context;
    }

    // As per docs, you may use views as key objects directly 
    // if they aren't too complex
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View view = inflater.inflate(R.layout.item, null);
        container.addView(view);
        return view;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }

    @Override
    public int getCount() {
        return 10;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    // Important: page takes all available width by default,
    // so let's override this method to fit 5 pages within single screen
    @Override
    public float getPageWidth(int position) {
        return 0.2f;
    }
}

Jako výsledek budete mít horizontálně rolovací widget s adaptérem, jako je tento: enter image description here

9
fraggjkee

Vyvinula jsem logiku, abych to udělala bez použití externí knihovny horizontálního posuvníku, zde je horizontální pohled, kterého jsem dosáhl a zaslal jsem svou odpověď zde: https://stackoverflow.com/a/33301582/5479863

Moje odpověď json je následující: 

{"searchInfo":{"status":"1","message":"Success","clist":[{"id":"1de57434-795e-49ac-0ca3-5614dacecbd4","name":"Theater","image_url":"http://52.25.198.71/miisecretory/category_images/movie.png"},{"id":"62fe1c92-2192-2ebb-7e92-5614dacad69b","name":"CNG","image_url":"http://52.25.198.71/miisecretory/category_images/cng.png"},{"id":"8060094c-df4f-5290-7983-5614dad31677","name":"Wine-shop","image_url":"http://52.25.198.71/miisecretory/category_images/beer.png"},{"id":"888a90c4-a6b0-c2e2-6b3c-561788e973f6","name":"Chemist","image_url":"http://52.25.198.71/miisecretory/category_images/chemist.png"},{"id":"a39b4ec1-943f-b800-a671-561789a57871","name":"Food","image_url":"http://52.25.198.71/miisecretory/category_images/food.png"},{"id":"c644cc53-2fce-8cbe-0715-5614da9c765f","name":"College","image_url":"http://52.25.198.71/miisecretory/category_images/college.png"},{"id":"c71e8757-072b-1bf4-5b25-5614d980ef15","name":"Hospital","image_url":"http://52.25.198.71/miisecretory/category_images/hospital.png"},{"id":"db835491-d1d2-5467-a1a1-5614d9963c94","name":"Petrol-Pumps","image_url":"http://52.25.198.71/miisecretory/category_images/petrol.png"},{"id":"f13100ca-4052-c0f4-863a-5614d9631afb","name":"ATM","image_url":"http://52.25.198.71/miisecretory/category_images/atm.png"}]}}

Soubor rozvržení:

    <?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:weightSum="5">    
    <fragment
        Android:id="@+id/map"
        Android:name="com.google.Android.gms.maps.SupportMapFragment"
        Android:layout_width="match_parent"
        Android:layout_height="0dp"
        Android:layout_weight="4" />
    <HorizontalScrollView
        Android:id="@+id/horizontalScroll"
        Android:layout_width="match_parent"
        Android:layout_height="0dp"
        Android:layout_weight="1">

        <LinearLayout
            Android:id="@+id/ll"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:gravity="center"
            Android:orientation="horizontal">    
        </LinearLayout>
    </HorizontalScrollView>
</LinearLayout>

soubor třídy:

LinearLayout linearLayout = (LinearLayout) findViewById(R.id.ll);
        for (int v = 0; v < collectionInfo.size(); v++) {
            /*---------------Creating frame layout----------------------*/

            FrameLayout frameLayout = new FrameLayout(ActivityMap.this);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, getPixelsToDP(90));
            layoutParams.rightMargin = getPixelsToDP(10);
            frameLayout.setLayoutParams(layoutParams);

            /*--------------end of frame layout----------------------------*/

            /*---------------Creating image view----------------------*/
            final ImageView imgView = new ImageView(ActivityMap.this); //create imageview dynamically
            LinearLayout.LayoutParams lpImage = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            imgView.setImageBitmap(collectionInfo.get(v).getCatImage());
            imgView.setLayoutParams(lpImage);
            // setting ID to retrieve at later time (same as its position)
            imgView.setId(v);
            imgView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    // getting id which is same as its position
                    Log.i(TAG, "Clicked on " + collectionInfo.get(v.getId()).getCatName());
                    // getting selected category's data list
                    new GetSelectedCategoryData().execute(collectionInfo.get(v.getId()).getCatID());
                }
            });
            /*--------------end of image view----------------------------*/

            /*---------------Creating Text view----------------------*/
            TextView textView = new TextView(ActivityMap.this);//create textview dynamically
            textView.setText(collectionInfo.get(v).getCatName());
            FrameLayout.LayoutParams lpText = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM | Gravity.CENTER);
            // Note: LinearLayout.LayoutParams 's gravity was not working so I putted Framelayout as 3 paramater is gravity itself
            textView.setTextColor(Color.parseColor("#43A047"));
            textView.setLayoutParams(lpText);
            /*--------------end of Text view----------------------------*/

            //Adding views at appropriate places
            frameLayout.addView(imgView);
            frameLayout.addView(textView);
            linearLayout.addView(frameLayout);

        }

 private int getPixelsToDP(int dp) {
        float scale = getResources().getDisplayMetrics().density;
        int pixels = (int) (dp * scale + 0.5f);
        return pixels;
    }

trik, který zde pracuje, je id, který jsem přidělil ImageView "imgView.setId (v)" a poté, co jsem použil onClickListener, že jsem znovu načítání id pohledu .... Také jsem komentoval uvnitř kódu tak Snadno srozumitelné, Doufám, že to bude velmi užitečné ... Happy Coding ... :)

 http://i.stack.imgur.com/lXrpG.png

7
Abdul Aziz

RecyclerView můžete použít v knihovně podpory. RecyclerView je zobecněná verze ListView, která podporuje:

  • Správce rozvržení pro umístění položek 
  • Výchozí animace pro běžné operace položek

Aplikace Android Recycler View Docs

5

To není moc odpověď, ale jak se o použití Horizontal Scroll View ?

4
Faisal

Udělal jsem hodně hledání řešení tohoto problému. Krátká odpověď je, že neexistuje žádné dobré řešení, aniž by převažovaly soukromé metody a takové věci. Nejlepší, co jsem našel, bylo, že jsem to provedl od nuly rozšířením AdapterView. Je to docela nešťastné. Viz moje SO otázka o horizontálních ListViews .

3
Neil Traft

Musel jsem udělat to samé pro jeden z mých projektů a nakonec jsem psal i vlastní. Volal jsem to HorzListView je nyní součástí mé open source Aniqroid knihovny. 

http://aniqroid.sileria.com/doc/api/ (Podívejte se na stahování ve spodní části nebo použijte projekt Google Code pro zobrazení dalších možností stahování: http://code.google.com/p/ aniqroid/downloads/list )

Dokumentace třídy je zde: http://aniqroid.sileria.com/doc/api/com/sileria/Android/view/HorzListView.html

3
Sileria

Pro moji aplikaci používám HorizontalScrollView obsahující LinearLayout uvnitř, který má orientaci nastavenou na horizontální. Chcete-li přidat obrázky uvnitř, vytvořím ImageViews uvnitř aktivity a přidám je do mého LinearLayoutu. Například:

<HorizontalScrollView 
        Android:id="@+id/photo_scroll"
        Android:layout_width="wrap_content"
        Android:layout_height="0dp"
        Android:layout_weight="1"
        Android:scrollbars="horizontal"
        Android:visibility="gone">

        <LinearLayout 
            Android:id="@+id/imageview_holder"
            Android:layout_width="wrap_content"
            Android:orientation="horizontal"
            Android:layout_height="match_parent">

        </LinearLayout>
    </HorizontalScrollView>

To pro mě funguje naprosto v pořádku. V činnosti, kterou musím udělat, je něco jako kód níže:

LinearLayout imgViewHolder = findViewById(R.id.imageview_holder);
ImageView img1 = new ImageView(getApplicationContext());
//set bitmap
//set img1 layout params
imgViewHolder.add(img1);
ImageView img2 = new ImageView(getApplicationContext());
//set bitmap
//set img2 layout params
imgViewHolder.add(img2); 

Jak jsem řekl, že to funguje pro mě, a doufám, že to pomůže někomu, kdo to chce dosáhnout.

1
Jorge Cespedes

dobře můžete vždy vytvářet vaše textviews dynamicky a nastavit onclicklisteners, jako byste udělali s adaptérem

0
weakwire

HorizontialListView nemůže fungovat, pokud jsou data v adaptéru zapojena do jiného podprocesu. Všechno běží 100% na UI thread.This je velký problém v multithread. Myslím, že použití HorizontialListView není nejlepším řešením pro vaše problem.HorzListView je lepší way.You prostě nahradit předchozí Galerie s HorzListView.You nemusí upravovat kód o adapter.Then vše jde tak, jak doufáte.See https: //stackoverflow.com/a/12339708/1525777 o HorzListView.

0
Europa

Použil jsem horizontální listview link v mém projektu & mám dobré výsledky. Byl jsem zpočátku používán devsmart knihovna, ale dal mi nějaké problémy. Takže nejlepší způsob, jak používat horizontální listview odkaz jak to obnovilo mé problémy & také jsem nedávno spustil svou aplikaci na Google PlayStore pomocí této knihovny & dostal pěknou odpověď od uživatelů. Doporučuji vám použít stejnou knihovnu, kterou jsem výše zmínil, aby se horizontálně zobrazoval seznam. Užívat si :)

0
Tiger

Existuje skvělá knihovna, která se nazývá TwoWayView , je velmi snadno implementovatelná, stačí zahrnout knihovnu projektu do vašeho pracovního prostoru a přidat ji jako projekt knihovny do původního projektu a poté postupujte podle následujících kroků, které jsou původně zde zmíněno :

Nejprve přidejme styl označující orientaci ListView (Horizontální nebo vertikální) v (res/values ​​/ styles.xml):

<style name="TwoWayView">
    <item name="Android:orientation">horizontal</item>
</style>

Pak,

V XML rozvržení použijte následující kód pro přidání TwoWayView:

<org.lucasr.twowayview.TwoWayView 
     xmlns:Android="http://schemas.Android.com/apk/res/Android"
     xmlns:tools="http://schemas.Android.com/tools"
     xmlns:app="http://schemas.Android.com/apk/res-auto"
     Android:id="@+id/lvItems"
     style="@style/TwoWayView"
     Android:layout_width="match_parent"
     Android:layout_height="match_parent"
     Android:drawSelectorOnTop="false"
     tools:context=".MainActivity" />

a nakonec to jen deklarovat a vypořádat se s ním jako s jakoukoli pravidelnou ListView:

TwoWayView lvTest = (TwoWayView) findViewById(R.id.lvItems);

Všechny metody ListView zde budou fungovat jako obvykle, ale je zde pouze jeden rozdíl, který jsem si všiml, což je při nastavení režimu výběru metoda setChoiceMode nebere hodnotu int, ale hodnotu z enum nazvanou ChoiceMode, takže list_view.setChoiceMode(ListView.CHOICE_MODE_SINGLE); bude lvTest.setChoiceMode(ChoiceMode.SINGLE); // or MULTIPLE or NONE.

0
Muhammed Refaat