ListView
横向きにすることは可能ですか?ギャラリービューを使用してこれを実行しましたが、選択したアイテムが自動的に画面の中央に表示されます。選択したアイテムを、クリックした場所と同じ場所にしたくない。この問題を修正するにはどうすればよいですか?私の考えはListView
、水平スクロールで設定することでした。あなたのアイデアを共有しますか?
ListView
横向きにすることは可能ですか?ギャラリービューを使用してこれを実行しましたが、選択したアイテムが自動的に画面の中央に表示されます。選択したアイテムを、クリックした場所と同じ場所にしたくない。この問題を修正するにはどうすればよいですか?私の考えはListView
、水平スクロールで設定することでした。あなたのアイデアを共有しますか?
回答:
Androidのドキュメントに従ってRecyclerView
、リストビューでアイテムを整理し、水平方向に表示する新しい方法です
利点:
についての詳細RecyclerView
:
サンプル:
下のブロックを追加して、ListView
垂直から水平に
コードスニペット
LinearLayoutManager layoutManager= new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, false);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(layoutManager);
Paulは自分のライブラリのバグを修正したり、ユーザーの修正を受け入れたりしません。これが、同様の機能を持つ別のライブラリを提案する理由です。
https://github.com/sephiroth74/HorizontalVariableListView
更新:2013年7月24日、作者(sephiroth74)がandroid 4.2.2 ListViewのコードを元に完全書き換え版をリリースしました。私はそれが前のバージョンが持っていたすべてのエラーを持っているわけではなく、うまく機能していると言わなければなりません!
@Paul回答は優れたソリューションへのリンクですが、コードでは項目の子に対してonClickListenersを使用できません(コールバック関数が呼び出されることはありません)。私はしばらくの間、解決策を見つけるのに苦労しており、そのコードで変更する必要があるものを誰かにここに投稿することにしました(誰かがそれを必要とする場合に備えて)。
オーバーライドをdispatchTouchEvent
上書きする代わりにonTouchEvent
。同じコードを使用しdispatchTouchEvent
てメソッドを削除します(この2つの違いはhttp://developer.android.com/guide/topics/ui/ui-events.html#EventHandlersで確認できます)
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean handled = mGesture.onTouchEvent(event);
return handled;
}
次に、アイテムの子からイベントを盗んでに渡すonTouchEvent
か、それらに処理させるかを決定する次のコードを追加します。
@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);
}
}
最後に、クラスで変数を宣言することを忘れないでください:
private float mInitialX;
private float mInitialY;
GoogleはAndroid Support Library v7 21.0.0を導入したため、RecyclerViewを使用して項目を水平にスクロールできます。RecyclerViewウィジェットは、ListViewのより高度で柔軟なバージョンです。
RecyclerViewを使用するには、依存関係を追加するだけです。
com.android.support:recyclerview-v7:23.0.1
ここにサンプルがあります:
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);
}
}
RecyclerViewの詳細:
これは少し遅れますが、誰かが後で来た場合に備えて投稿します。
Android Lプレビューの時点でのサポートライブラリには、RecyclerView
希望どおりの機能を備えたがあります。
今、あなただけのLプレビューSDKを通してそれを得ることができ、あなたの設定する必要がありますminSdk
にしますL
。ただし、必要なファイルをすべてプロジェクトにコピーして、Lが正式にリリースされるまでそのまま使用できます。
こちらからプレビュードキュメントをダウンロードできます。
警告:Recycler ViewのAPIは変更される可能性があり、バグがある可能性があります。
更新しました
水平リストビューのソースコードは次のとおりです。
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView myList = findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);
LinearLayoutManager
-ここを参照してください:stackoverflow.com/questions/28460300/...を
これをlibsフォルダーに入れ、右クリックして[ライブラリーとして追加]を選択します
今main.xmlにこのコードを入れてください
<com.devsmart.android.ui.HorizontalListView
android:id="@+id/hlistview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
画像付きの水平リストビューが必要な場合は、今度はActivityクラスに、このコードを入れます
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;
}
実際には非常に単純です:リストビューを回転させて横に配置します
mlistView.setRotation(-90);
次に、子を膨らませると、それはgetViewメソッド内にあるはずです。子供を回転させてまっすぐに立ちます:
mylistViewchild.setRotation(90);
編集: リストビューが回転後に適切にフィットしない場合は、次のようにこのRotateLayout内にリストビューを配置します。
<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>
私の解決策は単にViewPager
ウィジェットを使用することです。のように中央に固定されておらずGallery
、ビューをリサイクルするための組み込み機能があります(などListView
)。水平スクロール可能なリストを扱うときはいつでも、Google Playアプリで同様のアプローチを目にするかもしれません。
PagerAdapter
そこで拡張し、いくつかの微調整を実行するだけです。
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;
}
}
その結果、次のように、水平スクロール可能なウィジェット付きウィジェットが作成されます。
注:AndroidはRecyclerViewを使用した水平リストビューをサポートするようになったため、RecyclerViewの詳細については、この回答は非推奨になりました。https: //developer.android.com/reference/android/support/v7/widget/RecyclerView
私は外部の水平スクロールビューライブラリを使用せずにそれを実行するロジックを開発しました。これは私が達成した水平ビューです。ここに私の答えを投稿しました:https ://stackoverflow.com/a/33301582/5479863
私のjson応答はこれです:
{"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"}]}}
レイアウトファイル:
<?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>
クラスファイル:
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;
}
ここで機能しているトリックは、ImageView "imgView.setId(v)"に割り当てたIDです。その後、onClickListenerを適用した後、ビューのIDを再度フェッチしています...コード内にもコメントしているので、それが理解しやすいこと、これが非常に役立つことを願っています... Happy Coding ... :)
getPixelsToDP()
か?
これはそれほどの答えではありませんが、水平スクロールビューを使用するのはどうですか。
サポートライブラリのRecyclerViewを使用できます。RecyclerViewは、以下をサポートするListViewの汎用バージョンです。
私はこの問題の解決策を探すために多くのことを行いました。簡単に言えば、プライベートメソッドやその種のものをオーバーライドしない限り、適切な解決策はありません。私が見つけた最良のことは、を拡張して自分でゼロから実装することAdapterView
でした。それはかなり悲惨です。水平方向のリストビューに関する私の質問を参照してください。
fillListDown()
メソッドでは、最後のリストアイテムの下端を追跡する必要があるということです。しかし、実際に最後のアイテム(adapter.getCount()-1)を作成するまで、そのエッジがどこにあるかはわかりません。したがって、そのアイテムが作成されるまで待ってから、エッジの場所を保存できます。それがわかったら、mListTopが0以上で、リストの高さを超えないようにすることができます。
私は自分のプロジェクトの1つでも同じことをしなければならず、自分のプロジェクトも書きました。私はそれを呼ばHorzListViewが今の私のオープンソースの一部ですAniqroidライブラリ。
http://aniqroid.sileria.com/doc/api/ (下部にあるダウンロードを探すか、Googleコードプロジェクトを使用して、その他のダウンロードオプションを確認してください:http : //code.google.com/p/aniqroid/downloads/list)
クラスのドキュメントはこちら:http : //aniqroid.sileria.com/doc/api/com/sileria/android/view/HorzListView.html
私のアプリケーションでは、LinearLayoutを内部に含むHorizontalScrollViewを使用します。これは、方向が水平に設定されています。内部に画像を追加するために、アクティビティ内にImageViewを作成し、LinearLayoutに追加します。例えば:
<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>
これは私には完璧に機能します。アクティビティで私がしなければならないのは以下のコードのようなものです:
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);
私が言ったように、それは私にとってうまくいきます、そしてそれが同様にこれを達成しようとしている誰かに役立つことを願っています。
よくあなたは常にテキストビューなどを動的に作成し、アダプタで行うようにonclicklistenersを設定できます
アダプターのデータが別のスレッドに関係している場合、HorizontialListViewは機能しません。すべてが100%UIスレッドで実行されます。これはマルチスレッドの大きな問題です。HorizontialListViewを使用することは、問題の最善の解決策ではないと思います。HorzListViewは、より良い方法です。以前のギャラリーをHorzListViewに置き換えるだけです。アダプターに関するコードを変更する必要はありません。その後、すべてが希望どおりに進みます。https://を参照してくださいstackoverflow.com/a/12339708/1525777 HorzListViewについて。
プロジェクトで水平方向のリストビューリンクを使用していて 、良い結果が得られました。最初はdevsmartライブラリを使用していましたが、いくつか問題がありました。横向きのリストビューリンクを使用するのに最適な方法です。問題が解決しました。また、最近このライブラリを使用してGoogle PlayStoreでアプリを起動し、ユーザーから素晴らしい反応を得ました。だから私はあなたがリストビューを水平に表示するために私が上で述べたのと同じライブラリを使うことを勧めます。楽しい :)
TwoWayViewと呼ばれるそのための優れたライブラリがあり、実装は非常に簡単です。プロジェクトライブラリをワークスペースに含め、それをライブラリプロジェクトとして元のプロジェクトに追加してから、最初にここで言及されている次の手順に従います。
まず、(res / values / styles.xml)にListViewの方向(水平または垂直)を示すスタイルを追加します。
<style name="TwoWayView">
<item name="android:orientation">horizontal</item>
</style>
そして、
レイアウトXMLで、次のコードを使用して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" />
そして最後に、それを宣言して通常のように処理しますListView
:
TwoWayView lvTest = (TwoWayView) findViewById(R.id.lvItems);
すべてのメソッドListView
ここではいつものように意志の仕事が、私は選択モードを設定するときである、気づいた唯一の違いはあるが、この方法はsetChoiceMode
とりませんint
値ではなく、より価値enum
と呼ばれるがChoiceMode
、そうlist_view.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
なりますlvTest.setChoiceMode(ChoiceMode.SINGLE); // or MULTIPLE or NONE
。
ViewFlipperを使用してレイアウトXMLを含め、各レイアウトXMLに画像、リストビューを追加できます。