ListView
수평 으로 만들 수 있습니까? 갤러리보기를 사용하여이 작업을 수행했지만 선택한 항목이 화면 중앙에 자동으로 나타납니다. 선택한 항목을 클릭 한 지점에서 원하지 않습니다. 이 문제를 어떻게 해결할 수 있습니까? 내 생각은 ListView
가로 스크롤 로 설정하는 것이 었습니다 . 아이디어를 공유 하시겠습니까?
ListView
수평 으로 만들 수 있습니까? 갤러리보기를 사용하여이 작업을 수행했지만 선택한 항목이 화면 중앙에 자동으로 나타납니다. 선택한 항목을 클릭 한 지점에서 원하지 않습니다. 이 문제를 어떻게 해결할 수 있습니까? 내 생각은 ListView
가로 스크롤 로 설정하는 것이 었습니다 . 아이디어를 공유 하시겠습니까?
답변:
안드로이드 문서 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 를 사용할 수 없습니다 (콜백 함수는 호출되지 않습니다). 나는 해결책을 찾기 위해 한동안 고투 해 왔으며 여기에 해당 코드에서 수정해야 할 내용을 게시하기로 결정했습니다 (누군가 필요로하는 경우).
override를 dispatchTouchEvent
재정의 하는 대신 onTouchEvent
. 동일한 코드를 사용하고 dispatchTouchEvent
메소드를 삭제하십시오 ( 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 지원 라이브러리 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 preview 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"
/>
이미지가있는 가로 목록보기를 원하면이 클래스를 작성하십시오.
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);
편집 : 회전 후 ListView가 제대로 맞지 않으면 다음 과 같이 ListView를이 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
. 꽤 비참합니다. 수평 ListViews에 대한 내 SO 질문을 참조하십시오 .
fillListDown()
방법에서 마지막 목록 항목의 아래쪽 가장자리를 추적해야합니다. 그러나 실제로 마지막 항목 (adapter.getCount ()-1)을 만들 때까지 그 가장자리가 어디에 있는지 알 수 없습니다. 따라서 해당 항목이 생성 될 때까지 기다렸다가 가장자리 위치를 저장할 수 있습니다. 일단 알면 mListTop이 0보다 작고 목록의 높이보다 크지 않아야합니다.
나는 내 프로젝트 중 하나에 대해서도 똑같이해야했고 결국 내 자신의 글을 쓰게되었습니다. 필자는 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가 작동하지 않습니다. UI 스레드에서 모든 것이 100 % 실행됩니다. 이것은 멀티 스레드에서 큰 문제입니다. HorizontialListView를 사용하는 것이 문제에 대한 최상의 솔루션은 아니라고 생각합니다 .HorzListView가 더 좋은 방법입니다. 이전 갤러리를 HorzListView로 바꾸면됩니다. 어댑터에 대한 코드를 수정할 필요가 없습니다. 그러면 모든 것이 원하는 방식으로 진행됩니다 . HorzListView에 대해 stackoverflow.com/a/12339708/1525777 .
내가 사용했다 수평 목록보기 링크를 내 프로젝트에 & I는 좋은 결과를 얻었다. 처음에는 devsmart 라이브러리를 사용 했지만 몇 가지 문제가있었습니다. 가로 목록보기 링크 를 사용하여 문제를 복구하고 최근 에이 라이브러리를 사용하여 Google Play 스토어에서 앱을 시작하고 사용자로부터 좋은 반응을 얻었습니다. 따라서 위에서 언급 한 것과 동일한 라이브러리를 사용하여 목록보기를 가로로 표시하는 것이 좋습니다. 즐겨 :)
TwoWayView 라는 훌륭한 라이브러리가 있습니다. 구현하기 쉽고 프로젝트 라이브러리를 작업 공간에 포함시키고 원래 프로젝트에 라이브러리 프로젝트로 추가 한 다음 원래 언급 된 다음 단계를 따르십시오 .
먼저 (res / values / styles.xml)에서 ListView의 방향 (수평 또는 수직)을 나타내는 스타일을 추가해 보겠습니다.
<style name="TwoWayView">
<item name="android:orientation">horizontal</item>
</style>
그때,
Layout 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에 대한 이미지, 목록보기를 추가 할 수 있습니다