RecyclerView實現點擊回復效果
效果展示
Activity的布局文件
<?xml version="1.0" encoding="utf-8"?>
<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"
android:fitsSystemWindows="true"
tools:context="com.goucai.merchant.activity.store_manager.MessageBoardActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/message_board_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</LinearLayout>
這個布局文件中只包含了一個recyclerView.也就是這次我們要實現的主體文件,今天我們所有的操作都要在這個recyclerView中實現
RecyclerView 的item的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="75dp">
<ImageView
android:id="@+id/message_board_user_icon"
android:layout_marginLeft="18dp"
android:layout_marginTop="11dp"
android:src="@drawable/baicai"
android:layout_width="60dp"
android:layout_height="60dp" />
<LinearLayout
android:layout_marginRight="10dp"
android:layout_marginLeft="21dp"
android:orientation="vertical"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="40dp">
<TextView
android:id="@+id/message_board_user_name"
android:layout_marginTop="11dp"
android:textColor="@color/store_manager_textcolor"
android:textSize="18sp"
android:text="小張"
android:singleLine="true"
android:layout_width="110dp"
android:layout_height="25dp" />
<TextView
android:id="@+id/message_board_state"
android:layout_weight="1"
android:layout_marginTop="7dp"
android:gravity="top"
android:textSize="14sp"
android:textColor="@color/store_manager_textcolor"
android:text="好評"
android:layout_width="0dp"
android:layout_height="25dp" />
<TextView
android:id="@+id/message_board_time"
android:textSize="14sp"
android:text="18:18"
android:layout_width="50dp"
android:layout_height="25dp" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:textSize="14dp"
android:id="@+id/message_board_message"
android:textColor="@color/gray01"
android:text="工欲善其事,必先利其器,iOS開發中不僅要學會Xcode的基本操作,而且還得學會一些Xcode的使用技巧,如掌握常用的快捷鍵等,還有就是今天要說到的Xcode插件,下面我就為大家介紹幾款開發中比較常用的Xcode插件。"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="@+id/message_replay_btn"
android:visibility="invisible"
android:text="回復"
android:textColor="@color/white"
android:background="@color/colorPrimary"
android:layout_width="66dp"
android:layout_height="28dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<EditText
android:id="@+id/message_board_message_edit"
android:visibility="gone"
android:layout_marginTop="10dp"
android:layout_gravity="center_horizontal"
android:background="@drawable/message_board_dialog_icon"
android:layout_width="325dp"
android:layout_height="109dp" />
</LinearLayout>
這個布局文件看起來非常復雜,其實是非常簡單的,只不過由於我是用用LinearLayout寫的,需要實現多層嵌套,所以看起非常復雜,最后的效果圖就是下面這樣
在這個布局文件中有一個比較關鍵的地方,就是我們需要先寫出,item點擊以后出現的效果,然后再將沒有點擊的時候不需要展示的控件隱藏,也就是設置控件的Visibility.
例如我的布局文件中的
<Button
android:id="@+id/message_replay_btn"
android:visibility="invisible"
android:text="回復"
android:textColor="@color/white"
android:background="@color/colorPrimary"
android:layout_width="66dp"
android:layout_height="28dp" />
和
<EditText
android:id="@+id/message_board_message_edit"
android:visibility="gone"
android:layout_marginTop="10dp"
android:layout_gravity="center_horizontal"
android:background="@drawable/message_board_dialog_icon"
android:layout_width="325dp"
android:layout_height="109dp" />
之所以一個設置為Gone,一個設置為invisible時因為。GONE是徹底隱藏,並且不占用空間。因為我們的EditText需要沒點擊的時候收起來,所以一定要設置為GONE。而invisible只是不可見,仍然占用空間,如果我們將Button設置為GONE的話,就會導致左邊的評價擠過來,所以需要設置為invisible
activity的代碼
在activity中,我們只需要實現所有應該RecyclerView 應該實現的即可,沒有什么特別的。代碼如下
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.goucai.merchant.R;
import com.goucai.merchant.adapter.MessageBoardAdapter;
import com.goucai.merchant.beans.MessageBoard;
import com.goucai.merchant.lib.SystemBarTintManager;
import com.goucai.merchant.utils.Util;
import java.util.ArrayList;
import java.util.List;
public class MessageBoardActivity extends AppCompatActivity implements MessageBoardAdapter.OnClickOrderListener {
private RecyclerView recyclerView;
private MessageBoardAdapter adapter;
private List<MessageBoard> mList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message_board);
initDate();
initView();
}
private void initDate() {
mList=new ArrayList<>();
for (int i=0;i<20;i++){
MessageBoard messageBoard=new MessageBoard();
messageBoard.setUserName("name"+i);
mList.add(messageBoard);
}
}
private void initView() {
((TextView)findViewById(R.id.title)).setText("評價留言");
recyclerView= (RecyclerView) findViewById(R.id.message_board_recyclerview);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new MessageBoardAdapter(this,mList);
// adapter.setOnRecyclerViewListener(this);
adapter.setOnClickOrderListener(this);
recyclerView.setAdapter(adapter);
}
@Override
public void onClickItem(View itemView, View view, EditText e, Button btn) {
Util.Log_i("點擊了:評價留言"+itemView.getTag());
adapter.notifyDataSetChanged();
}
}
現在重點來了,就是RecyleView的Adapate的實現
先上代碼,一會再來講解
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.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.goucai.merchant.R;
import com.goucai.merchant.beans.MessageBoard;
import com.goucai.merchant.utils.Util;
import java.util.List;
/**
* Created by ruiqin on 2016/6/18.
*/
public class MessageBoardAdapter extends RecyclerView.Adapter{
private List<MessageBoard> mList;
private View mView;
private Context mContext;
private LayoutInflater inflater;
private int selPosition=10001;
public MessageBoardAdapter(Context context, List<MessageBoard> list){
mList=list;
mContext=context;
inflater=LayoutInflater. from(mContext);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// mView= View.inflate(mContext,R.layout.item_order_layout,parent);
mView=inflater.inflate(R.layout.item_message_board_layout,parent,false);
MyViewHolder viewHolder=new MyViewHolder(mView);
Util.Log_i("onCreateViewHolder");
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((MyViewHolder)holder).username.setText(mList.get(position).getUserName());
holder.itemView.setTag(position);
if (position>10000){
return;
}
if (position==selPosition){
((MyViewHolder)holder).editText.setVisibility(View.VISIBLE);
((MyViewHolder)holder).replayBtn.setVisibility(View.VISIBLE);
}else {
((MyViewHolder)holder).editText.setVisibility(View.GONE);
((MyViewHolder)holder).replayBtn.setVisibility(View.INVISIBLE);
}
}
@Override
public int getItemCount() {
// Util.Log_i("listsize="+mList.size());
return mList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView username;
private EditText editText;
private Button replayBtn;
public MyViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
username= (TextView) itemView.findViewById(R.id.message_board_user_name);
editText= (EditText) itemView.findViewById(R.id.message_board_message_edit);
replayBtn= (Button) itemView.findViewById(R.id.message_replay_btn);
}
@Override
public void onClick(View v) {
v.findViewById(R.id.message_board_message_edit).setVisibility(View.VISIBLE);
v.findViewById(R.id.message_replay_btn).setVisibility(View.VISIBLE);
selPosition=Integer.parseInt(itemView.getTag().toString());
MessageBoardAdapter.this.notifyDataSetChanged();
// editTextList.get(Integer.parseInt(itemView.getTag().toString())).setVisibility(View.VISIBLE);
// btnList.get(Integer.parseInt(itemView.getTag().toString())).setVisibility(View.VISIBLE);
onClickOrderListener.onClickItem(itemView,v,editText,replayBtn);
}
}
public void setOnClickOrderListener(OnClickOrderListener onClickOrderListener)
{
this.onClickOrderListener =onClickOrderListener;
}
public OnClickOrderListener onClickOrderListener;
public interface OnClickOrderListener {
void onClickItem(View itemView, View view,EditText editText,Button replayBtn);
}
}
好了,要實現點擊效果首先我們要坐的就是定義一個全局變量
private int selPosition=10001;
你問我為什么初始值要賦值為10001,一會兒再來說明
定義好全局變量以后,我們就需要實現Item的點擊事件了。我們需要在OnClick
里面將selPosition值賦值為當前點擊的值
selPosition=Integer.parseInt(itemView.getTag().toString());
這里我們是通過在onBindViewHolder中給itemView添加TAG,然后在Onclick中取出,來實現的。
v.findViewById(R.id.message_board_message_edit).setVisibility(View.VISIBLE);
v.findViewById(R.id.message_replay_btn).setVisibility(View.VISIBLE);
這段代碼的作用就是將當前選擇的item的EditText和Button設置為可見。
其實到這里,我們的主要功能已經實現了,點擊Item后,item會擴展,並出現Button和EditText。
但是現在還有兩個問題,一個是上一個點擊的Item會依然保持被點擊狀態,不會回復到原來狀態,而且我們滑動到下面,再滑動到原來位置的時候,你點擊的那個item會回復到最初始的狀態。
出現這個問題的原因是android為了節省資源,在你將item滑出屏幕的時候,會對item進行回收。之后再在onBindViewHolder中進行重繪。
知道了問題的原因以后,我們所要做的就是在onBindViewHolder中告訴系統,哪個item我點擊了,你重繪的時候,請恢復到你回收前的狀態,實現的代碼如下
if (selPosition>10000){
return;
}
if (position==selPosition){
((MyViewHolder)holder).editText.setVisibility(View.VISIBLE);
((MyViewHolder)holder).replayBtn.setVisibility(View.VISIBLE);
}else {
((MyViewHolder)holder).editText.setVisibility(View.GONE);
((MyViewHolder)holder).replayBtn.setVisibility(View.INVISIBLE);
}
現在看到這里你應該理解我將selPosition設置為10001的原因了吧,因為如果我將selPosition設置為0的話,就會導致進入這個activity的時候,第0個item就已經處於選中狀態了。當然你也可以設置-1,然后前面加個判斷啥的。
最后我們再在Onclick中加一個
MessageBoardAdapter.this.notifyDataSetChanged();
解決點擊一個item上個item仍然處於選中狀態的情況!