Android App 개발 에서 RecyclerView 를 사용 하여 Gallery 갤러리 의 인 스 턴 스 를 실현 합 니 다.
22478 단어 RecyclerViewAndroid
RecyclerView 는 Android 5.0 materials design 의 구성 요소 중 하나 로 CardView,Palette 등 이 해당 한다.이름 을 보면 우 리 는 약간의 실 마 리 를 알 수 있다.맞 아,그것 의 주요 특징 은 바로 재 활용 이다.Listview 의 Adapter 에서 View Holder 의 재 활용 을 실현 할 수 있다 는 것 을 알 고 있 습 니 다.RecyclerView 는 View Holder 를 재 활용 하고 ListView,GridView,폭포 흐름 을 쉽게 실현 할 수 있 는 결합 도가 더 낮은 방식 을 제공 합 니 다.
RecyclerView 사용 의 기본 사고방식
우선 gradle 의존 라 이브 러 리 에 추가 해 야 합 니 다. compile 'com.android.support:recyclerview-v7:21.+' 。eclipse 라면 android-support-v7-recyclerview.jar 를 직접 가 져 오 면 됩 니 다.
/**
* Adapter
*/
mRecyclerView.setAdapter(mListAdapter);
/**
*
*/
mRecyclerView.setLayoutManager(linearLayoutManager);
/**
* item
*/
mRecyclerView.addItemDecoration(itemDecoration);
/**
* item
*/
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
RecyclerView 를 사용 하려 면 기본적으로 4 단계 가 필요 합 니 다.ListView 는 Adapter 만 설정 하 는 것 보다 RecyclerView 의 사용 이 복잡 해 보 입 니 다.그러나 그의 맞 춤 형 제작 가능성 이 더욱 높 아 졌 다.너 는 자신의 분할 선 스타일 이나 item 의 애니메이션 을 스스로 맞 출 수 있다.갤러리 효과 구현
RecyclerView 는 여기 서 ListView 의 업그레이드 버 전 으로 볼 수 있 습 니 다.아래 에서 살 때 먼저 RecyclerView 의 용법 을 소개 한 다음 에 일정한 분석 을 거 칩 니 다.마지막 으로 RecyclerView 를 사용자 정의 하여 우리 가 필요 로 하 는 앨범 효 과 를 실현 합 니 다.
1.RecyclerView 의 기본 용법
우선 주 Activity 의 레이아웃 파일:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v7.widget.RecyclerView
android:id="@+id/id_recyclerview_horizontal"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_centerVertical="true"
android:background="#FF0000"
android:scrollbars="none" />
</RelativeLayout>
Item 의 레이아웃 파일:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="120dp"
android:layout_height="120dp"
android:background="@drawable/item_bg02" >
<ImageView
android:id="@+id/id_index_gallery_item_image"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_margin="5dp"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/id_index_gallery_item_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/id_index_gallery_item_image"
android:layout_centerHorizontal="true"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:textColor="#ff0000"
android:text="some info"
android:textSize="12dp" />
</RelativeLayout>
데이터 어댑터:
package com.example.zhy_horizontalscrollview03;
import java.util.List;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
public class GalleryAdapter extends
RecyclerView.Adapter<GalleryAdapter.ViewHolder>
{
private LayoutInflater mInflater;
private List<Integer> mDatas;
public GalleryAdapter(Context context, List<Integer> datats)
{
mInflater = LayoutInflater.from(context);
mDatas = datats;
}
public static class ViewHolder extends RecyclerView.ViewHolder
{
public ViewHolder(View arg0)
{
super(arg0);
}
ImageView mImg;
TextView mTxt;
}
@Override
public int getItemCount()
{
return mDatas.size();
}
/**
* ViewHolder
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i)
{
View view = mInflater.inflate(R.layout.activity_index_gallery_item,
viewGroup, false);
ViewHolder viewHolder = new ViewHolder(view);
viewHolder.mImg = (ImageView) view
.findViewById(R.id.id_index_gallery_item_image);
return viewHolder;
}
/**
*
*/
@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int i)
{
viewHolder.mImg.setImageResource(mDatas.get(i));
}
}
데이터 어댑터 와 BaseAdapter 의 비교 에 상당 한 변화 가 생 겼 음 을 볼 수 있 습 니 다.주로 세 가지 방법 이 있 습 니 다.이 를 통 해 알 수 있 듯 이 RecyclerView 는 View Holder 에 대해 서도 일정한 패 키 징 을 했 습 니 다.그러나 자세히 살 펴 보면 궁금 한 점 이 있 습 니 다.ListView 에 getView 가 View 를 Item 으로 되 돌려 주 는 레이아웃 이 있 습 니 다.그러면 이 Item 의 모습 은 어디서 제어 합 니까?
사실은 이 렇 습 니 다.저희 가 만 든 ViewHolder 는 RecyclerView 를 계승 해 야 합 니 다.ViewHolder 는 RecyclerView 의 구 조 를 계승 해 야 합 니 다.ViewHolder 의 구 조 는 View 에 들 어가 야 합 니 다.이 View 는 저희 ListView getView 의 convertView(즉,inflate 가 필요 한 item 레이아웃 이 들 어 와 야 합 니 다)에 해당 합 니 다.
또 하 나 는 ListView 에서 convertView 는 재 활용 입 니 다.RecyclerView 에 서 는 ViewHolder 를 캐 시 단위 로 한 다음 에 convertView 를 ViewHolder 의 구성원 변수 로 ViewHolder 에 유지 합 니 다.즉,화면 에 10 개의 항목 이 표시 되 지 않 으 면 10 개의 ViewHolder 캐 시 를 만 듭 니 다.매번 재 활용 하 는 것 은 ViewHolder 입 니 다.그래서 그 는 getView 라 는 방법 을 onCreate View Holder 로 바 꾸 었 다.관심 있 는 사람 이 Log 를 인쇄 해서 테스트 해 보 세 요.
마지막 으로 Activity 에서 사용:
package com.example.zhy_horizontalscrollview03;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Window;
public class MainActivity extends Activity
{
private RecyclerView mRecyclerView;
private GalleryAdapter mAdapter;
private List<Integer> mDatas;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initDatas();
//
mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview_horizontal);
//
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
mRecyclerView.setLayoutManager(linearLayoutManager);
//
mAdapter = new GalleryAdapter(this, mDatas);
mRecyclerView.setAdapter(mAdapter);
}
private void initDatas()
{
mDatas = new ArrayList<Integer>(Arrays.asList(R.drawable.a,
R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e,
R.drawable.f, R.drawable.g, R.drawable.h, R.drawable.l));
}
}
사용 하기에 도 편리 합 니 다.유일한 차이 점 은 LayoutManager 를 설정 하 는 것 입 니 다.현재 하나의 실현 클래스 만 있 습 니 다.바로 LinearLayoutManager 입 니 다.수평 또는 수직 으로 설정 할 수 있 습 니 다.마지막 효과 그림:
효과 가 아주 좋 습 니 다.이것 이 바로 RecyclerView 의 기본 적 인 용법 입 니 다.하지만 아버 지 를 속 이 는 곳 을 발견 할 수 있 을 것 입 니 다.setOnitem ClickListener 라 는 반전 을 제공 하지 않 았 습 니 다.이렇게 아버 지 를 속 일 까요?
2.RecyclerView 에 OnItemClickListener 리 셋 추가
제공 되 지 는 않 았 지만 Onitem ClickListener 를 추가 하 는 것 은 우리 에 게 식 은 죽 먹 기다.
Adapter 에 이 반전 인 터 페 이 스 를 추가 하기 로 했 습 니 다.
package com.example.zhy_horizontalscrollview03;
import java.util.List;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
public class GalleryAdapter extends
RecyclerView.Adapter<GalleryAdapter.ViewHolder>
{
/**
* ItemClick
* @author zhy
*
*/
public interface OnItemClickLitener
{
void onItemClick(View view, int position);
}
private OnItemClickLitener mOnItemClickLitener;
public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener)
{
this.mOnItemClickLitener = mOnItemClickLitener;
}
private LayoutInflater mInflater;
private List<Integer> mDatas;
public GalleryAdapter(Context context, List<Integer> datats)
{
mInflater = LayoutInflater.from(context);
mDatas = datats;
}
public static class ViewHolder extends RecyclerView.ViewHolder
{
public ViewHolder(View arg0)
{
super(arg0);
}
ImageView mImg;
TextView mTxt;
}
@Override
public int getItemCount()
{
return mDatas.size();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i)
{
View view = mInflater.inflate(R.layout.activity_index_gallery_item,
viewGroup, false);
ViewHolder viewHolder = new ViewHolder(view);
viewHolder.mImg = (ImageView) view
.findViewById(R.id.id_index_gallery_item_image);
return viewHolder;
}
@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int i)
{
viewHolder.mImg.setImageResource(mDatas.get(i));
// ,
if (mOnItemClickLitener != null)
{
viewHolder.itemView.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
mOnItemClickLitener.onItemClick(viewHolder.itemView, i);
}
});
}
}
}
간단 합 니 다.인 터 페 이 스 를 만 들 고 입 구 를 설정 한 다음 에 onBindView Holder 에서 판단 하면 됩 니 다.마지막 으로 주 Activity 에 감청 설정:
mAdapter = new GalleryAdapter(this, mDatas);
mAdapter.setOnItemClickLitener(new OnItemClickLitener()
{
@Override
public void onItemClick(View view, int position)
{
Toast.makeText(MainActivity.this, position+"", Toast.LENGTH_SHORT)
.show();
}
});
mRecyclerView.setAdapter(mAdapter);
자,이렇게 하면 됩 니 다.효과 도 를 보 세 요.효과 가 좋 습 니 다.그 다음 에 앨범 효과 로 바 꾸 고 싶 습 니 다.즉,위 에 큰 그림 이 표시 되 어 있 고 아래 의 RecyclerView 는 그림 전환 의 지시기 로 바 꾸 고 싶 습 니 다.
3.사용자 정의 RecyclerView 스크롤 시 내용 연동
우선 레이아웃 수정:
레이아웃 파일:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<ImageView
android:id="@+id/id_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_margin="10dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_launcher" />
</FrameLayout>
<com.example.zhy_horizontalscrollview03.MyRecyclerView
android:id="@+id/id_recyclerview_horizontal"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_gravity="bottom"
android:background="#FF0000"
android:scrollbars="none" />
</LinearLayout>
큰 그림 을 표시 하 는 영역 을 추가 하고 RecyclerView 를 자신의 정의 로 바 꿉 니 다.그리고 사용자 정의 RecyclerView 코드 를 보십시오.
package com.example.zhy_horizontalscrollview03;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class CopyOfMyRecyclerView extends RecyclerView
{
public CopyOfMyRecyclerView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
private View mCurrentView;
/**
*
*/
private OnItemScrollChangeListener mItemScrollChangeListener;
public void setOnItemScrollChangeListener(
OnItemScrollChangeListener mItemScrollChangeListener)
{
this.mItemScrollChangeListener = mItemScrollChangeListener;
}
public interface OnItemScrollChangeListener
{
void onChange(View view, int position);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
mCurrentView = getChildAt(0);
if (mItemScrollChangeListener != null)
{
mItemScrollChangeListener.onChange(mCurrentView,
getChildPosition(mCurrentView));
}
}
@Override
public boolean onTouchEvent(MotionEvent e)
{
if (e.getAction() == MotionEvent.ACTION_MOVE)
{
mCurrentView = getChildAt(0);
// Log.e("TAG", getChildPosition(getChildAt(0)) + "");
if (mItemScrollChangeListener != null)
{
mItemScrollChangeListener.onChange(mCurrentView,
getChildPosition(mCurrentView));
}
}
return super.onTouchEvent(e);
}
}
스크롤 할 때 되 돌 리 는 인 터 페 이 스 를 정의 한 다음 onTouchEvent 에서 ACTION 을 감청 합 니 다.MOVE,사용자 손가락 이 미 끄 러 질 때 현재 첫 번 째 View 를 계속 되 돌려 줍 니 다~내 가 getChildAt(0)과 getChildPosition()을 어떻게 알 았 는 지 에 대해 서 는 처음에 getFirst Visible Item 이라는 방법 이 있 는 줄 알 았 는데 나중에 발견 한 것 이 있 습 니까?그런데 getRecycledView Pool()을 발 견 했 습 니 다.이름 을 보 니 Viewholder 의 캐 시 대기 열 이 라 고 생각 합 니 다.이 대기 열의 첫 번 째 는 제 가 원 하 는 View 가 아 닙 니까?나중에 성공 하지 못 했 습 니 다.나 는 그 내부 의 View 를 관찰 한 결과 첫 번 째 로 보 이 는 것 은 첫 번 째 child 이 고 getChild Position 이라는 방법 에 대해 알 아 차 렸 다.
현재 효과:
예전 의 그 예 와 효 과 는 똑 같 습 니 다.하지만 저 는 변 화 를 주 고 싶 습 니 다.Gallery 나 앨범 의 인디케이터,아래 에 1000 여 장의 그림 이 있 을 것 이 라 고 생각 합 니 다.저 는 손가락 이 화면 에서 미 끄 러 질 때 그림 이 자동 으로 전환 되 는 것 을 좋아 할 뿐만 아니 라.나 는 또 내 가 지시기 에 속 도 를 주면 손가락 이 떠 나 도 아래 가 미 끄 러 지고 위 가 연결 되 기 를 바란다.그리고 최적화 도 하고 싶 어 요.바로 ACTIONMOVE 에서 리 턴 을 하면 촉발 하 는 빈도 가 너무 높 아서 이론 적 으로 한 장의 그림 이 한 번 만 촉발 할 수 있 습 니 다~~
4.진정한 Gallery 효 과 를 최적화 하고 만 듭 니 다.
손가락 이 떠 나 도 연결 되 기 를 바 라 는 이상 ACTION 뿐만 아니 라MOVE 는 감청 이 필요 합 니 다.가속도 도 감청 해 야 합 니 다.속도 가 일정 치 에 도달 한 다음 에 계속 이동 해 야 합 니 다~다시 정리 해 보 세 요.이렇게 번 거 롭 게 굴 러 갈 수 있 잖 아 요.그러면 OnScrollListener 가 있어 야 합 니 다.한 번 보 세 요.과연 있 습 니 다.하하 하~하늘 이 도와 주 셨 습 니 다.다음 에 수정 한 코드 를 보 겠 습 니 다.
package com.example.zhy_horizontalscrollview03;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.OnScrollListener;
import android.util.AttributeSet;
import android.view.View;
public class MyRecyclerView extends RecyclerView implements OnScrollListener
{
/**
* View
*/
private View mCurrentView;
private OnItemScrollChangeListener mItemScrollChangeListener;
public void setOnItemScrollChangeListener(
OnItemScrollChangeListener mItemScrollChangeListener)
{
this.mItemScrollChangeListener = mItemScrollChangeListener;
}
public interface OnItemScrollChangeListener
{
void onChange(View view, int position);
}
public MyRecyclerView(Context context, AttributeSet attrs)
{
super(context, attrs);
// TODO Auto-generated constructor stub
this.setOnScrollListener(this);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
mCurrentView = getChildAt(0);
if (mItemScrollChangeListener != null)
{
mItemScrollChangeListener.onChange(mCurrentView,
getChildPosition(mCurrentView));
}
}
@Override
public void onScrollStateChanged(int arg0)
{
}
/**
*
* , View ,
*/
@Override
public void onScrolled(int arg0, int arg1)
{
View newView = getChildAt(0);
if (mItemScrollChangeListener != null)
{
if (newView != null && newView != mCurrentView)
{
mCurrentView = newView ;
mItemScrollChangeListener.onChange(mCurrentView,
getChildPosition(mCurrentView));
}
}
}
}
나 는 onTouchEvent 재 작성 방법 을 포기 하고 RecyclerView.OnScrollListener 인 터 페 이 스 를 실현 한 다음 에 감청 을 설정 하여 onScrolled 에서 판단 하도록 했다.최적화:저 는 한 멤버 의 변 화 를 사용 하여 현재 첫 번 째 View 를 저장 합 니 다.첫 번 째 View 가 변 했 을 때 만 리 셋 합 니 다~너무 완벽 합 니 다~
MainActivity 보기:
package com.example.zhy_horizontalscrollview03;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.zhy_horizontalscrollview03.GalleryAdapter.OnItemClickLitener;
import com.example.zhy_horizontalscrollview03.MyRecyclerView.OnItemScrollChangeListener;
public class MainActivity extends Activity
{
private MyRecyclerView mRecyclerView;
private GalleryAdapter mAdapter;
private List<Integer> mDatas;
private ImageView mImg ;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mImg = (ImageView) findViewById(R.id.id_content);
mDatas = new ArrayList<Integer>(Arrays.asList(R.drawable.a,
R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e,
R.drawable.f, R.drawable.g, R.drawable.h, R.drawable.l));
mRecyclerView = (MyRecyclerView) findViewById(R.id.id_recyclerview_horizontal);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
mRecyclerView.setLayoutManager(linearLayoutManager);
mAdapter = new GalleryAdapter(this, mDatas);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setOnItemScrollChangeListener(new OnItemScrollChangeListener()
{
@Override
public void onChange(View view, int position)
{
mImg.setImageResource(mDatas.get(position));
};
});
mAdapter.setOnItemClickLitener(new OnItemClickLitener()
{
@Override
public void onItemClick(View view, int position)
{
// Toast.makeText(getApplicationContext(), position + "", Toast.LENGTH_SHORT)
// .show();
mImg.setImageResource(mDatas.get(position));
}
});
}
}
코드 는 변 함 이 없어 요.설정 이 하나 더 생 겼 어 요.효과 그림:
핸드폰 이 위 에서 이동 할 때의 변 화 를 지원 할 뿐만 아니 라 제 가 속 도 를 주면 아래 에서 계속 굴 러 가면 위 에서 도 계속 변화 합 니 다~대 박~사진 한 장 씩 리 셋 하면 효율 도 상당히 좋 습 니 다.
자,이 블 로 그 를 보고 여러분 들 이 RecyclerView 에 대해 어느 정도 알 게 되 었 을 거 라 고 믿 습 니 다.심지어 하나의 컨트롤 을 어떻게 개조 하 는 지 에 대해 서도 알 게 되 었 습 니 다~
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Android】RecyclerView+RadioButton의 작성RadioGroup을 사용하지 않고 작성합니다. RecyclerView 배치 activity_main.xml RadioButton 배치 view_item.xml RecyclerView 용 어댑터 작성. 어느 버튼을 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.