it-swarm.com.de

Horizontale ListView in Android?

Ist es möglich, die ListView horizontal zu gestalten? Ich habe dies mit der Galerieansicht gemacht, aber das ausgewählte Element wird automatisch in der Mitte des Bildschirms angezeigt. Ich möchte, dass das ausgewählte Element nicht an derselben Stelle ist, auf die ich geklickt habe. Wie kann ich dieses Problem beheben? Meine Idee war es, die ListView mit horizontalem Scroll einzustellen. Teilen Sie Ihre Idee mit

201
Praveen

Laut Android-Dokumentation ist RecyclerView die neue Möglichkeit, die Elemente in der Listenansicht zu organisieren und horizontal anzuzeigen

Vorteile:

  1. Durch die Verwendung des Recyclerview-Adapters wird das ViewHolder-Muster automatisch Implementiert
  2. Animation ist leicht durchzuführen
  3. Viele weitere Funktionen

Weitere Informationen zu RecyclerView:

  1. grokkingandroid.com
  2. antonioleiva.com

Probe:

survivingwithandroid.com

Fügen Sie einfach den unteren Block hinzu, um die ListView von horizontal zu horizontal zu machen

Code-Auszug

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

Paul macht sich nicht die Mühe, Fehler in seiner Bibliothek zu beheben oder Benutzer-Korrekturen zu akzeptieren. Deshalb schlage ich eine andere Bibliothek mit ähnlicher Funktionalität vor: 

https://github.com/sephiroth74/HorizontalVariableListView

Update: am 24. Juli 2013 veröffentlichte der Autor (sephiroth74) eine komplett neu geschriebene Version basierend auf dem Code von Android 4.2.2 ListView. Ich muss sagen, dass es nicht alle Fehler der vorherigen Version hat und großartig funktioniert!

60
Malachiasz

@Paul answer verlinkt auf eine großartige Lösung, der Code erlaubt jedoch nicht die Verwendung von onClickListeners für untergeordnete Elemente (die Rückruffunktionen werden nie aufgerufen). Ich habe seit einiger Zeit Mühe gehabt, eine Lösung zu finden, und ich habe beschlossen, hier zu veröffentlichen, was Sie in diesem Code ändern müssen (falls es jemand braucht).

Anstatt dispatchTouchEvent zu überschreiben, überschreiben Sie onTouchEvent. Verwenden Sie den gleichen Code von dispatchTouchEvent und löschen Sie die Methode (Sie können den Unterschied zwischen den beiden hier lesen: http://developer.Android.com/guide/topics/ui/ui-events.html#EventHandlers )

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

Fügen Sie dann den folgenden Code hinzu, der beschließt, das Ereignis von den untergeordneten Elementen zu stehlen und es unserer onTouchEvent zu geben, oder es von ihnen behandelt zu lassen.

@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);
    }
}

Vergessen Sie nicht, die Variablen in Ihrer Klasse zu deklarieren:

private float mInitialX;
private float mInitialY;
28
Xavi Gil

Seit Google die Android Support Library v7 21.0.0 eingeführt hat, können Sie RecyclerView verwenden, um Objekte horizontal zu scrollen. Das RecyclerView-Widget ist eine erweiterte und flexible Version von ListView.

Um RecyclerView zu verwenden, fügen Sie einfach eine Abhängigkeit hinzu:

com.Android.support:recyclerview-v7:23.0.1

Hier ist ein Beispiel:

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);
    }
}

Weitere Informationen zu RecyclerView:

23
klimat

Dies ist etwas (sehr) spät, aber ich poste das, falls später jemand kommt.

Die Support Library ab der Android L-Vorschau hat eine RecyclerView , die genau das macht, was Sie wollen.

Im Moment können Sie es nur über das L-Preview-SDK erhalten und Sie müssen Ihre minSdk auf L setzen. Sie können jedoch alle erforderlichen Dateien in Ihr Projekt kopieren und auf diese Weise verwenden, bis L offiziell beendet ist.

Sie können die Vorschau-Dokumente hier herunterladen.

Warnung: Die API für die Recycler-Ansicht kann sich ändern und Fehler aufweisen.

Aktualisierte

Der Quellcode für die horizontale Listenansicht lautet:

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

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

Laden Sie die JAR-Datei von hier herunter.

legen Sie es in Ihren libs-Ordner, klicken Sie mit der rechten Maustaste darauf und wählen Sie "Als Bibliothek hinzufügen". 

jetzt in main.xml diesen Code einfügen

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

jetzt in der Aktivitätsklasse, wenn Sie die horizontale Listenansicht mit Bildern verwenden möchten, geben Sie diesen Code ein

  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

Eigentlich ist es sehr einfach : Drehen Sie einfach die Listenansicht, um sie auf die Seite zu legen

mlistView.setRotation(-90);

Nach dem Aufblasen der Kinder sollte sich dies innerhalb der getView-Methode befinden. Sie drehen die Kinder, um aufrecht zu stehen:

 mylistViewchild.setRotation(90);

Bearbeiten: Wenn Ihre ListView nach dem Drehen nicht richtig passt, platzieren Sie die ListView in diese RotateLayout wie folgt:

 <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

Meine Lösung ist, einfach das Widget ViewPager zu verwenden. Es ist nicht als Gallery in der Mitte gesperrt und verfügt über integrierte Funktionen zum Wiederherstellen von Ansichten (als ListView). In der Google Play-App sehen Sie möglicherweise einen ähnlichen Ansatz, wenn Sie mit horizontal scrollbaren Listen arbeiten.

Sie müssen lediglich PagerAdapter erweitern und dort einige Änderungen vornehmen:

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;
    }
}

Als Ergebnis haben Sie ein horizontal scrollbares Widget mit einem Adapter wie folgt: enter image description here

9
fraggjkee

Ich habe eine Logik entwickelt, um dies zu tun, ohne eine externe horizontale Scrollview-Bibliothek zu verwenden. Hier ist die horizontale Ansicht, die ich erreicht habe, und ich habe meine Antwort hier gepostet: https://stackoverflow.com/a/33301582/5479863

Meine json Antwort lautet: 

{"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"}]}}

Layoutdatei:

    <?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>

klassendatei:

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;
    }

ein Trick, der hier funktioniert, ist die ID, die ich ImageView zugewiesen habe "imgView.setId (v)" und danach den onClickListener anwenden, auf den ich die ID der View abrieße .... Ich habe auch den Code so kommentiert dass es leicht zu verstehen ist. Ich hoffe, das kann sehr nützlich sein. Glückliches Codieren ... :)

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

7
Abdul Aziz

Sie können RecyclerView in der Support-Bibliothek verwenden. RecyclerView ist eine verallgemeinerte Version von ListView, die Folgendes unterstützt:

  • Ein Layout-Manager zum Positionieren von Elementen 
  • Standardanimationen für allgemeine Elementoperationen

Android Recycler View Docs

Dies ist keine große Antwort, aber wie wäre es mit einer Horizontal Scroll View ?

4
Faisal

Ich habe viel nach einer Lösung für dieses Problem gesucht. Die kurze Antwort lautet: Es gibt keine gute Lösung, ohne private Methoden und dergleichen zu überschreiben. Das Beste, was ich gefunden habe, war, es selbst von Grund auf zu implementieren, indem es AdapterView erweitert. Es ist ziemlich elend. Siehe meine SO - Frage zu horizontalen ListViews .

3
Neil Traft

Ich musste dasselbe für eines meiner Projekte tun und am Ende schrieb ich auch mein eigenes. Ich nannte es HorzListView ist jetzt Teil meiner Open Source Aniqroid -Bibliothek. 

http://aniqroid.sileria.com/doc/api/ (Suchen Sie unten nach Downloads oder verwenden Sie das Google-Code-Projekt, um weitere Downloadoptionen anzuzeigen: http://code.google.com/p/ aniqroid/downloads/list )

Die Klassendokumentation ist hier: http://aniqroid.sileria.com/doc/api/com/sileria/Android/view/HorzListView.html

3
Sileria

Für meine Anwendung verwende ich eine HorizontalScrollView, die LinearLayout enthält, deren Ausrichtung auf horizontal eingestellt ist. Um Bilder darin hinzuzufügen, erstelle ich ImageViews innerhalb der Aktivität und füge sie meinem LinearLayout hinzu. Zum Beispiel:

<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>

Und das funktioniert perfekt für mich. In der Aktivität muss ich nur etwas wie den folgenden Code tun:

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); 

Wie gesagt, das funktioniert für mich und ich hoffe, es hilft auch jemandem, der dies erreichen möchte.

1
Jorge Cespedes

nun, Sie können Ihre Textansichten usw. immer dynamisch erstellen und Ihre Onclicklistener wie mit einem Adapter einstellen

0
weakwire

HorizontialListView kann nicht ausgeführt werden, wenn die Daten im Adapter in einem anderen Thread vorhanden sind. Alles läuft zu 100% auf dem UI-Thread. Dies ist ein großes Problem bei Multithread. Ich denke, die Verwendung von HorizontialListView ist nicht die beste Lösung für Ihr Problem. HorzListView ist eine bessere Möglichkeit. Sie ersetzen einfach Ihre vorherige Galerie durch HorzListView. Sie müssen den Code für den Adapter nicht ändern. Dann läuft alles so, wie Sie es sich erhoffen. Siehe https: //stackoverflow.com/a/12339708/1525777 about HorzListView.

0
Europa

Ich hatte in meinem Projekt horizontal listview link verwendet und gute Ergebnisse erzielt. Ich war anfangs devsmart -Bibliothek verwendet worden, aber es gab mir einige Probleme. Also, die beste Möglichkeit, horizontal listview link zu verwenden, um meine Probleme zu beheben. Außerdem habe ich vor kurzem meine App in Google PlayStore mit dieser Bibliothek gestartet. Daher empfehle ich Ihnen, dieselbe Bibliothek zu verwenden, die ich oben erwähnte, um die Listenansicht horizontal anzuzeigen. Genießen :)

0
Tiger

Dafür gibt es eine großartige Bibliothek, genannt TwoWayView . Es ist sehr einfach zu implementieren. Fügen Sie einfach die Projektbibliothek in Ihren Arbeitsbereich ein und fügen Sie sie Ihrem ursprünglichen Projekt als Bibliotheksprojekt hinzu. Befolgen Sie anschließend die folgenden Schritte ursprünglich hier erwähnt :

Zuerst fügen wir einen Stil hinzu, der die Ausrichtung der ListView angibt (horizontal oder vertikal) in (res/values ​​/ styles.xml):

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

Dann,

Verwenden Sie in Ihrer Layout-XML den folgenden Code, um TwoWayView hinzuzufügen:

<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" />

und schließlich deklarieren Sie es einfach und behandeln Sie es wie jede reguläre ListView:

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

Alle Methoden von ListView funktionieren hier wie gewohnt, aber es gibt nur einen Unterschied, den ich feststellte. Beim Einstellen des Auswahlmodus nimmt die Methode setChoiceMode keinen int-Wert an, sondern einen Wert von enum mit dem Namen ChoiceMode, also list_view.setChoiceMode(ListView.CHOICE_MODE_SINGLE);. wird lvTest.setChoiceMode(ChoiceMode.SINGLE); // or MULTIPLE or NONE sein.

0
Muhammed Refaat