目录
源码:GitHub - ldaadl/AndroidDevelopment1: 第一次作业
一.作业要求
作业2: 1、请在实验二的基础上,对有recycleView的页面进行点击跳转设计。比如,某一tab页是新闻列表,则点击某一行能跳转到新闻详情页面; 2、本次作业考查的基础原理是对activity的生命周期的理解以及状态转变操作; 3、作业以博客形式提交; 4、提交截止日期:10月25日24:00。
二.分析与实现
一.分析
我之前做的是一个类微信界面而不是新闻列表界面,在我看来,点击一行聊天记录然后跳转到具体聊天界面完全可以用fragment实现,但是作业明确要求了考察activity,所以我还是选择在点击一行聊天记录时跳转到新的activity界面。
新的activity的xml文件由三部分组成,顶栏、底栏和中间部分,中间部分我打算使用recyclerView。
二.实现
1.xml文件的具体实现
这一次作业相较于上一次实验,新增了这些文件:
message_botton和message_top是底栏和顶栏,activity_main2中包含这两个文件还有一个recyclerView,而message_item1和item2则是填充进recyclerView中的内容,他们两个的区别是,item1是对方的消息,item2是自己的消息,两者布局不同,所以要区分开。
2.java文件的具体实现
实现跳转:
我们来一步一步看怎么将功能实现,首先我们需要的是点击一个item后实现跳转到一个新的activity,并显示相应的聊天记录。这里实现跳转并不难,难的是如何区分点击了不同的item以方便传入activity不同数据。
好在上一次实验时,我做过左划删除的功能,左划删除也必须鉴别左划了哪个item,所以我们这里的操作可以借鉴上一次的操作,我上一次是重写了控件recyclerView,以增加左划删除的功能,这一次同样可以增加点击跳转的功能:
在重写的类SwipeRecyclerView.java中
/*。。。。。。。。。。。。。。。。。。。。。 */ /** * 点击的监听事件 */ private OnClickListener mClickListener; public void setOnClickListener(OnClickListener listener){ this.mClickListener = listener; } /*。。。。。。。。。。。。。。。。。。。。。*/ public interface OnClickListener{ void onClick(int position, String id); } /*。。。。。。。。。。。。。。。。。。。。。*/ // 在 onTouchEvent 中新增 // 对某个item的选中完成在onTouchEvent中 // 对点击item的监听 mCurItemLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mClickListener != null){ mClickListener.onClick(curSelectPosition, ""); } } });
我们还需要在FragmentMessage.java 中增加:
// 设置点击监听 // 这里有疑问,重写的onClick的上下文是当前环境的吗? recyclerView.setOnClickListener(new SwipeRecyclerView.OnClickListener() { @Override public void onClick(int position, String id) { Intent intent = new Intent(context,MainActivity2.class); // **** intent.putExtra(key[0],data.get(position).get(key[0]).toString()); intent.putExtra(key[1],data.get(position).get(key[1]).toString()); intent.putExtra(key[2],Integer.parseInt(data.get(position).get(key[2]).toString())); Toast.makeText(context,"跳转页面",Toast.LENGTH_LONG).show(); // SystemClock.sleep(1000); startActivityForResult(intent, 0); } });
这里重写了onClick方法,供SwipeRecyclerView.java使用,以实现具体的onClick功能。
在跳转的activity中显示消息:
跳转完成后,我们需要在跳转后的activity的recyclerView中填充我们的消息,这里的难点在于,消息是有两种的的,对方的消息和我们的消息布局是不同的,也就是说我们需要在一个recyclerView中填充两种item,我后来查找过资料,这可以在Adapter通过viewType实现,但是我选择了自己的方法:
我在实验后发现,Adapter的生命周期是:构造器->getItemCount->onCreateViewHolder->MyViewHolder.MyViewHolder->onBindViewHolder
除了构造器是一次调用外,其余部分每在recyclerView上实现一个item就会循环一次。选择item.xml文件渲染的步骤在onCreateViewHolder和MyViewHolder.MyViewHolder中,所以我定义了一个int whichItem来决定某一次渲染item时该渲染哪个item.xml,这个whichItem在构造器中初始化来判断第一个item使用那个item.xml,之后在onBindViewHolder中判断下一次渲染item该使用哪一个item。
AdapterOfMessage.java
public class AdapterOfMessage extends RecyclerView.Adapter<AdapterOfMessage.MyViewHolder> { private View itemView; private Context context; private List<Map<String, Object>> data; // whichItem == 0 表示我自己 private int whichItem; public AdapterOfMessage(List<Map<String, Object>> data, Context context) { this.context = context; this.data = data; // 第一次设置whichItem // 空字符串表示我自己 if(data.get(0).get("联系人") == "") whichItem = 0; else whichItem = 1; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { if(whichItem==0){ itemView = LayoutInflater.from(context).inflate(R.layout.message_item2,parent,false); }else{ itemView = LayoutInflater.from(context).inflate(R.layout.message_item1,parent,false); } MyViewHolder myViewHolder = new MyViewHolder(itemView); return myViewHolder; } // 在onbind中设置下一个item是谁 @RequiresApi(api = Build.VERSION_CODES.N) @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { holder.headphoto.setImageResource(Integer.parseInt(data.get(position).getOrDefault("头像",R.drawable.person1).toString())); holder.message.setText(data.get(position).get("消息").toString()); if(position+1<data.size()){ if(data.get(position+1).get("联系人").toString() == "") whichItem = 0; else whichItem = 1; } } @Override public int getItemCount() { return data.size(); } public class MyViewHolder extends RecyclerView.ViewHolder { ImageView headphoto; TextView message; public MyViewHolder(@NonNull View itemView) { super(itemView); if (whichItem==0){ headphoto = itemView.findViewById(R.id.myImage); message = itemView.findViewById(R.id.myMessage); }else{ headphoto = itemView.findViewById(R.id.heImage); message = itemView.findViewById(R.id.heMessage); } } } }
MainActivity2.java的内容就比较简单了,但是值得一说的是,我想通过点击顶栏的返回按钮实现返回,而不想通过点击系统按钮返回,我原以为比较难实现,结果很简单,在监听按钮中增加finish()即可。
public class MainActivity2 extends AppCompatActivity { private TextView textView; private RecyclerView recyclerView; private List<Map<String, Object>> message_logging; private AdapterOfMessage myAdapter; private ImageView button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); textView = findViewById(R.id.topWho); Log.d("life", "2:onCreate"); Intent intent = getIntent(); Bundle data = intent.getExtras(); String name = data.getString("联系人"); textView.setText(name); textView.setText(name); String message = data.getString("消息"); int photo = data.getInt("头像"); Log.d("message",name+message+photo); recyclerView = findViewById(R.id.message_recyclerView); message_logging = new ArrayList<Map<String, Object>>(); // 绑定2条消息 String[] key = new String[]{"联系人", "消息", "头像"}; Map<String, Object> item1 = new HashMap<String, Object>(); item1.put(key[0],name); item1.put(key[1],message); item1.put(key[2],photo); Map<String, Object> item2 = new HashMap<String, Object>(); item2.put(key[0],""); item2.put(key[1],"你好吗"); item2.put(key[2],R.drawable.me); message_logging.add(item2); message_logging.add(item1); myAdapter = new AdapterOfMessage(message_logging, this); LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(RecyclerView.VERTICAL); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(myAdapter); // 监听返回 button = findViewById(R.id.message_return); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { finish(); } }); } @Override protected void onStart() { super.onStart(); // life可以在logcat中搜索该标签 Log.d("life","2:onStart"); } @Override protected void onPostResume() { super.onPostResume(); Log.d("life","2:onResume"); } @Override protected void onPause() { super.onPause(); Log.d("life","2:onPause"); } @Override protected void onStop() { super.onStop(); Log.d("life","2:onStop"); } @Override protected void onRestart() { super.onRestart(); Log.d("life","2:onRestart"); } @Override protected void onDestroy() { super.onDestroy(); Log.d("life","2:onDestroy"); } @Override public void finish() { super.finish(); } }
这是效果图,很丑
这时跳转到新的activity和返回时的生命周期: