2016-11-14 88 views
12

我已經使用Android的RecyclerView幾次製作了一個項目列表,但它是一個相當複雜的過程。通過衆多在線作品之一(this,thisthis很好),但我正在尋找一個可以複製和粘貼以快速啓動並運行的裸骨頭示例。只有以下功能是必要的:簡單的Android RecyclerView示例

  • 垂直佈局
  • 每行一個單一的TextView
  • 來響應點擊事件

因爲我希望這個好幾次,我終於決定請在下面回答我未來的參考資料和你的答案。

回答

49

以下是一個看起來像下圖所示的最簡單示例。

RecyclerView with a list of animal names

開始與空活動。您將執行以下任務來添加RecyclerView。您只需在每個部分複製並粘貼代碼即可。稍後,您可以對其進行定製以適應您的需求。

  • 添加依賴於搖籃
  • 添加XML佈局文件活動,爲RecyclerView行
  • 充分利用RecyclerView適配器
  • 初始化RecyclerView您的活動

更新搖籃依賴關係

確保以下依賴項在您的應用程序gradle.build文件:

implementation 'com.android.support:appcompat-v7:27.0.2' 
implementation 'com.android.support:recyclerview-v7:27.0.2' 

您可以更新的版本號是什麼the most current。如果您仍在使用Android Studio 2.x,請使用compile而不是implementation

創建活動佈局

添加RecyclerView到您的XML佈局。

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/rvAnimals" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 

</RelativeLayout> 

創建行佈局

每一行都在我們RecyclerView只會有一個單一的TextView。創建一個新的佈局資源文件。

recyclerview_row。XML

<?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="wrap_content" 
    android:orientation="horizontal" 
    android:padding="10dp"> 

    <TextView 
     android:id="@+id/tvAnimalName" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textSize="20sp"/> 

</LinearLayout> 

創建適配器

RecyclerView需要一個適配器來填充每一行中的意見與您的數據。創建一個新的java文件。

MyRecyclerViewAdapter.java

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> { 

    private List<String> mData; 
    private LayoutInflater mInflater; 
    private ItemClickListener mClickListener; 

    // data is passed into the constructor 
    MyRecyclerViewAdapter(Context context, List<String> data) { 
     this.mInflater = LayoutInflater.from(context); 
     this.mData = data; 
    } 

    // inflates the row layout from xml when needed 
    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = mInflater.inflate(R.layout.recyclerview_row, parent, false); 
     return new ViewHolder(view); 
    } 

    // binds the data to the TextView in each row 
    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     String animal = mData.get(position); 
     holder.myTextView.setText(animal); 
    } 

    // total number of rows 
    @Override 
    public int getItemCount() { 
     return mData.size(); 
    } 


    // stores and recycles views as they are scrolled off screen 
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 
     TextView myTextView; 

     ViewHolder(View itemView) { 
      super(itemView); 
      myTextView = itemView.findViewById(R.id.tvAnimalName); 
      itemView.setOnClickListener(this); 
     } 

     @Override 
     public void onClick(View view) { 
      if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition()); 
     } 
    } 

    // convenience method for getting data at click position 
    String getItem(int id) { 
     return mData.get(id); 
    } 

    // allows clicks events to be caught 
    void setClickListener(ItemClickListener itemClickListener) { 
     this.mClickListener = itemClickListener; 
    } 

    // parent activity will implement this method to respond to click events 
    public interface ItemClickListener { 
     void onItemClick(View view, int position); 
    } 
} 

  • 雖然不是絕對必要,我包括用於監聽行上點擊事件的功能。這在舊版ListViews中可用,並且是一種常見需求。如果你不需要它,你可以刪除這些代碼。

初始化RecyclerView在活動

下面的代碼添加到您的主要活動。

MainActivity.java

public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener { 

    MyRecyclerViewAdapter adapter; 

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

     // data to populate the RecyclerView with 
     ArrayList<String> animalNames = new ArrayList<>(); 
     animalNames.add("Horse"); 
     animalNames.add("Cow"); 
     animalNames.add("Camel"); 
     animalNames.add("Sheep"); 
     animalNames.add("Goat"); 

     // set up the RecyclerView 
     RecyclerView recyclerView = findViewById(R.id.rvAnimals); 
     recyclerView.setLayoutManager(new LinearLayoutManager(this)); 
     adapter = new MyRecyclerViewAdapter(this, animalNames); 
     adapter.setClickListener(this); 
     recyclerView.setAdapter(adapter); 
    } 

    @Override 
    public void onItemClick(View view, int position) { 
     Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show(); 
    } 
} 

  • 注意,該活動實現了我們在適配器中定義的ItemClickListener。這使我們能夠處理onItemClick中的行單擊事件。

成品

就是這樣。你現在應該可以運行你的項目並獲得類似於頂部圖像的東西。

你打算在

添加行之間的分隔

您可以添加一個簡單的除法這樣

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), 
    layoutManager.getOrientation()); 
recyclerView.addItemDecoration(dividerItemDecoration); 

如果你想要的東西多一點複雜,請參閱以下答案:

上點擊更改排顏色

更新行

this answer瞭解如何添加,刪除和更新行。

Insert single item

進一步閱讀

+0

Exelente,muchisimas予格拉西亞斯POR角城exelente教程 –

0

依賴

compile 'com.android.support:appcompat-v7:25.3.1' 
    compile 'com.android.support:design:25.3.1' 
    compile 'com.android.support:multidex:1.0.1' 
    compile 'com.android.support:cardview-v7:25.3.1' 
    compile 'com.android.support:support-v4:25.3.1' 
    compile 'com.lguipeng.bubbleview:library:1.0.0' 
    compile 'com.larswerkman:HoloColorPicker:1.5' 
    compile 'com.mcxiaoke.volley:library-aar:1.0.0' 

一類項目按

import android.content.Context; 
import android.support.v7.widget.RecyclerView; 
import android.view.GestureDetector; 
import android.view.MotionEvent; 
import android.view.View; 

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener { 
    private OnItemClickListener mListener; 

    public interface OnItemClickListener { 
     public void onItemClick(View view, int position); 
    } 

    GestureDetector mGestureDetector; 

    public RecyclerItemClickListener(Context context, OnItemClickListener listener) { 
     mListener = listener; 
     mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { 
      @Override 
      public boolean onSingleTapUp(MotionEvent e) { 
       return true; 
      } 
     }); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) { 
     View childView = view.findChildViewUnder(e.getX(), e.getY()); 
     if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { 
      mListener.onItemClick(childView, view.getChildPosition(childView)); 
      return true; 
     } 
     return false; 
    } 

    @Override 
    public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { } 

    @Override 
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { 

    } 


} 

二等RecyclerView

import android.annotation.SuppressLint; 
import android.app.ProgressDialog; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.net.Uri; 
import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentTransaction; 
import android.support.v4.content.LocalBroadcastManager; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Toast; 

import com.android.volley.DefaultRetryPolicy; 
import com.android.volley.Request; 
import com.android.volley.RequestQueue; 
import com.android.volley.Response; 
import com.android.volley.VolleyError; 
import com.android.volley.toolbox.StringRequest; 
import com.android.volley.toolbox.Volley; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 
import java.util.ArrayList; 

public class SLByTopics extends Fragment { 


    public static ArrayList<MByTopics> byTopicsMainArrayList=new ArrayList<>(); 


    TabRefreshReceiver tabRefreshReceiver; 
    RecyclerView recyclerView; 
    SAdpByTopics sAdpByTopics; 
    public ArrayList<MByTopics> mByTopicsArrayList=new ArrayList<>(); 
    ProgressDialog progressDialog; 

    public SLByTopics(){ 
    } 

    @Override 
    public void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.sl_fragment_by_topics, container, false); 

     progressDialog = new ProgressDialog(getActivity()); 
     if (IsOnline.isNetworkAvailable(getActivity())) { 
      getCategoryTree(); 
     } else{ 
      IsOnline.showNoInterNetMessage(getActivity()); 
     } 
     tabRefreshReceiver = new TabRefreshReceiver(); 
     LocalBroadcastManager.getInstance(getContext()).registerReceiver(tabRefreshReceiver, new IntentFilter("BY_TOPICS")); 

     setUpView(view); 
     return view; 
    } 

    private void setUpView(View view) { 

     recyclerView=(RecyclerView)view.findViewById(R.id.by_topics_list_recyclerView); 
     LinearLayoutManager linearLayoutManager=new LinearLayoutManager(getActivity()); 
     linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
     recyclerView.setLayoutManager(linearLayoutManager); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 

     recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() { 
      @Override 
      public void onItemClick(View view, final int position) { 

       if (mByTopicsArrayList.get(position).getChild().size()>0){ 
        Intent intent = new Intent(getActivity(), SByTopicCategory.class); 
        intent.putExtra("selectedCategoryName",mByTopicsArrayList.get(position).getCatname()); 
        intent.putExtra("jsonData",mByTopicsArrayList.get(position).getMainTopicJson()); 
        startActivity(intent); 
        getActivity().overridePendingTransition(R.anim.activity_in, R.anim.activity_out); 
       }else { 
        Intent intent = new Intent(getActivity(), SByCategoryQuestionList.class); 
        intent.putExtra("selectedSubCategoryName",mByTopicsArrayList.get(position).getCatname()); 
        intent.putExtra("catID",mByTopicsArrayList.get(position).getId()); 
        startActivity(intent); 
        getActivity().overridePendingTransition(R.anim.activity_in, R.anim.activity_out); 
       } 
      } 
     })); 

    } 

    private class TabRefreshReceiver extends BroadcastReceiver { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      try { 
       FragmentTransaction ft = getFragmentManager().beginTransaction(); 
       ft.detach(SLByTopics.this).attach(SLByTopics.this).commit(); 
       LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(tabRefreshReceiver); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     } 
    } 








    private void getCategoryTree() { 
     progressDialog.setMessage("Please Wait..."); 
     progressDialog.setCancelable(false); 
     progressDialog.show(); 

     StringRequest stringRequest = new StringRequest(Request.Method.POST, Const.HOSTNAME + Const.STUDENT_GET_CATEGORY_TREE, 
       new Response.Listener<String>() { 
        @SuppressLint("LongLogTag") 
        @Override 
        public void onResponse(String response) { 
         try { 
          JSONObject object = new JSONObject(response); 
          String status = object.getString("status"); 
          int i = Integer.parseInt(status); 

          switch (i) { 

           case 0: 
            progressDialog.dismiss(); 
//         Toast.makeText(getActivity(), "getCategorySuccess", Toast.LENGTH_SHORT).show(); 
            Log.e("getCategoryTree Response", "getCategoryTree Response : " + response); 

            try { 



             byTopicsMainArrayList.clear(); 
             JSONArray info = object.getJSONArray("info"); 
             if (info.length() > 0) { 
              for (i = 0; i < info.length(); i++) { 
               JSONObject data = info.getJSONObject(i); 
               MByTopics mByTopics = new MByTopics(); 
               mByTopics.setId(data.getString("id")); 
               mByTopics.setCatname(data.getString("catname")); 
               mByTopics.setMainTopicJson(data.toString()); 

               JSONArray topicChildren = data.getJSONArray("children"); 
               ArrayList<SMByTopicCategory> byChildrenArrayList = new ArrayList<>(); 

               for (int j = 0; j < topicChildren.length(); j++) { 
                JSONObject topicChildrenData = topicChildren.getJSONObject(j); 
                SMByTopicCategory smByTopicCategory = new SMByTopicCategory(); 
                smByTopicCategory.setId(topicChildrenData.getString("id")); 
                smByTopicCategory.setCatname(topicChildrenData.getString("catname")); 
                smByTopicCategory.setChildTopicJson(topicChildrenData.toString()); 

                JSONArray topicChildrenQuestion = topicChildrenData.getJSONArray("children"); 
                ArrayList<SMByTopicSubCategory> byChildrenSubArrayList = new ArrayList<>(); 

                for (int k = 0; k < topicChildrenQuestion.length(); k++) { 
                 JSONObject topicChildrenSubData = topicChildrenQuestion.getJSONObject(k); 
                 SMByTopicSubCategory smByTopicSubCategory = new SMByTopicSubCategory(); 
                 smByTopicSubCategory.setId(topicChildrenSubData.getString("id")); 
                 smByTopicSubCategory.setCatname(topicChildrenSubData.getString("catname")); 
                 smByTopicSubCategory.setChildSubTopicJson(topicChildrenSubData.toString()); 

                 byChildrenSubArrayList.add(smByTopicSubCategory); 
                } 

                smByTopicCategory.setQuestions(byChildrenSubArrayList); 

                byChildrenArrayList.add(smByTopicCategory); 
               } 
               mByTopics.setChild(byChildrenArrayList); 
               byTopicsMainArrayList.add(mByTopics); 
              } 


              mByTopicsArrayList.clear(); 
              mByTopicsArrayList=byTopicsMainArrayList; 
              sAdpByTopics=new SAdpByTopics(mByTopicsArrayList,getActivity()); 
              recyclerView.setAdapter(sAdpByTopics); 
              sAdpByTopics.notifyDataSetChanged(); 

             } 

            }catch (Exception e){ 
             e.printStackTrace(); 
            } 
            break; 

           default: 
            progressDialog.dismiss(); 
//         Toast.makeText(getActivity(), "getCategoryError : " + response, Toast.LENGTH_SHORT).show(); 
            Log.e("getCategoryTree Not Response", "getCategoryTree Uploading Not Response : " + response); 
          } 

         } catch (JSONException e) { 
          e.printStackTrace(); 
         } 
        } 
       }, 
       new Response.ErrorListener() { 
        @Override 
        public void onErrorResponse(VolleyError error) { 
         progressDialog.dismiss(); 
         Log.e("getCategoryTree Error :","getCategoryTree Error :"+error.getMessage()); 
//      Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_LONG).show(); 
        } 
       }){ 

     };/* { 
      @Override 
      protected Map<String, String> getParams() throws AuthFailureError { 

       Map<String, String> map = new HashMap<String, String>(); 
//    map.put("uid", String.valueOf(ConfigManager.getUserId())); 
       return map; 
      } 
     };*/ 

     stringRequest.setRetryPolicy(new DefaultRetryPolicy(
       0, 
       DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
       DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 

     RequestQueue requestQueue = Volley.newRequestQueue(getActivity()); 
     requestQueue.add(stringRequest); 
    } 
} 

適配器類回收站項目

import android.app.Activity; 
import android.support.v7.widget.RecyclerView; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 
import java.util.ArrayList; 

public class SAdpByTopics extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 
     ArrayList<MByTopics> topicsArrayList=new ArrayList<>(); 
     Activity activity; 

public SAdpByTopics(ArrayList<MByTopics> topicsArrayList,Activity activity){ 
     this.topicsArrayList=topicsArrayList; 
     this.activity=activity; 
     } 

@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View itemeView= LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_by_topic_list,parent,false); 
     RecyclerView.ViewHolder holder=new Holder(itemeView); 
     holder.setIsRecyclable(false); 
     return holder; 
     } 

@Override 
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
final Holder classHolder = (Holder) holder; 
     try{ 
     classHolder.txt_topic_name.setText(topicsArrayList.get(position).getCatname()); 
     }catch (Exception e){ 
     e.printStackTrace(); 
     } 
     } 

@Override 
public int getItemCount() { 
     return topicsArrayList.size(); 
     } 


class Holder extends RecyclerView.ViewHolder implements View.OnClickListener { 
    TextView txt_topic_name; 

    public Holder(View itemView) { 
     super(itemView); 
     txt_topic_name = (TextView) itemView.findViewById(R.id.txt_topic_name); 
    } 

    @Override 
    public void onClick(View v) { 

    } 
} 
} 

模塊類

public class MByTopics { 

    String id; 
    String topicName; 
    String catname; 
    String MainTopicJson; 
    ArrayList<SMByTopicCategory> child; 
    ArrayList<SMByTopicSubCategory> questions; 



    public void setId(String id){ 
     this.id=id; 
    } 
    public String getId(){ 
     return id; 
    } 

    public void setCatname(String catname) { 
     this.catname = catname; 
    } 

    public String getCatname() { 
     return catname; 
    } 

    public void setTopicName(String topicName) { 
     this.topicName = topicName; 
    } 
    public String getTopicName() { 
     return topicName; 
    } 

    public void setChild(ArrayList<SMByTopicCategory> child) { 
     this.child = child; 
    } 


    public String getMainTopicJson() { 
     return MainTopicJson; 
    } 

    public void setMainTopicJson(String mainTopicJson) { 
     MainTopicJson = mainTopicJson; 
    } 


    public ArrayList<SMByTopicCategory> getChild() { 
     return child; 
    } 

    public void setQuestions(ArrayList<SMByTopicSubCategory> questions) { 
     this.questions = questions; 
    } 

    public ArrayList<SMByTopicSubCategory> getQuestions() { 
     return questions; 
    } 

    public ArrayList<MByTopics> getByTopicList() { 
     ArrayList<MByTopics> mByTopicsArrayList = new ArrayList<>(); 

     for (int i=0;i<11;i++){ 
      MByTopics mQuestionBankCategory=new MByTopics(); 

      if (i==1 || i== 5|| i==9){ 
       mQuestionBankCategory.setTopicName("Microeconomics"); 
      }else if (i==2 || i== 10|| i==6) { 
       mQuestionBankCategory.setTopicName("Macroeconomics"); 
      }else { 
       mQuestionBankCategory.setTopicName("Current Isssues"); 
      } 

      mByTopicsArrayList.add(mQuestionBankCategory); 
     } 

     return mByTopicsArrayList; 
    } 

} 
+2

解釋將是很好 – ThomasEdwin