安卓recyclerView,dialog,JSON,AsycnTask简单应用--备忘录

第二次作业要求做一个简单的小APP备忘录。可以添加删除更改recyclerView(也就是我们的备忘录)。

总的思路大概是先设计3个activity的xml文件,menu和recyclerView要多设计几个xml以便联系到一起。然后结合一些固定不变的代码和套路复制粘贴补全。

recyclerView是用arrayList实现的。安卓项目开始创建的时候,系统会自动帮我们加载arrayList到recyclerView里面。此后,每当attayList有变化,我们得手动通知程序重新加载arrayList到recyclerView里面去。具体方法是用mAdapter.notifyDataSetChanged(); 来通知Adapter重新加载。Adapter是recyclerView要求的几个类之一,负责将arrayList加载到recyclerView里面去。具体是通过三个方法(最后一个目前还不是十分清楚意义):第一是动态的管理view(对我这个APP来说就是大方框);第二是结合viewHolder将arrayList中的文字写道view(大方框,有单独的xml格式layout)里面去;第三个是返回arrayList里面的元素个数。ViewHolder也是要求的第二个类,作用是简化了繁琐的代码,通过它可以找到对应的view,不用一遍遍输入。然后很重要的一个问题是,当你选中一个方框时,你必须知道这个方框在arrayList的什么位置,否则你无法对它进行删除,编辑操作。其实很简单,用一个简单的函数,recyclerView.getChildAdapterPosition(v); 就可以找到这个位置。我这个备忘录的编辑和删除功能正式基于这一点。

Json是文本格式,通过一些特定的读写操作,我们可以在onPause或onStop哪儿的将安卓应用当前的信息记录进去,保存到硬盘或者或联网等等,这样下次再进入安卓的时候,我们在onCreat或onStart或onResume哪儿的里面先将Json导入一下,就可以避免因为onStop,onDestory导致的信息丢失。如果没有Json文件来保存信息,备忘录根本一点意义没有。

AsycnTask是安卓提供的一个类,提供多线程服务。一般导入轻量级的数据,比如Json数据之类的。在onCreate或合适的地方用一下。它通过三个泛型规范了传入类型,进度完成报告采用类型,返回类型。第二个类型为了增强用户互动,具体以后再根据规范详细看。

最后还有就是activity之间转移和信息的传递。是通过intent。intent可以将一个activity转移到另外一个activity,通过startActivity,当然,原来的activity一般就被onStop了。另外intent通过putExtra方法可作为activity之间信息传递的介质,保存一些东西进去,在另一个activity中按照“KEY”提取。然后该父activity也可以选择要不要接收子activity返回的数据,具体是通过startActivityForResult实现的。子Activity返回的数据在父Activity里面通过onActivityResult方法接收。我这个备忘录的编辑功能正式基于这一点。

mainfests: 记录全部的activity,设置好mainActivity。




    
        
            
                

                
            
        
        
        
    

EditActivity,点一个recyclerView就进入此activity,这里面返回键要重写,要显示dialog,让用户选择是保存还是放弃。还要在右上角有保存menu。

package com.example.multinotes;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;


public class EditActivity extends AppCompatActivity {

    private EditText title_Edit;
    private EditText content_Edit;
    private static final String TAG = "EditActivity";

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

        title_Edit = findViewById(R.id.title);
        content_Edit = findViewById(R.id.content);

        content_Edit.setMovementMethod(new ScrollingMovementMethod());
        content_Edit.setTextIsSelectable(true);

        title_Edit.setText(getIntent().getStringExtra("title"));
        content_Edit.setText(getIntent().getStringExtra("content"));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.action_menu2, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
            if(item.getItemId() == R.id.save) {
                //go to an activity that display version and author information.
                Intent data = new Intent();
                data.putExtra("title", title_Edit.getText().toString());
                data.putExtra("content", content_Edit.getText().toString());
                setResult(RESULT_OK, data);
                finish();
                return true;
            }
            else
                return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        if(content_Edit.getText().toString().equals("") && title_Edit.getText().toString().equals("")){
            showToast();
            super.onBackPressed();
        }
        else {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            //builder.setIcon(R.drawable.icon1);
            builder.setPositiveButton("Save", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    //position = mAdapter.getPosition();
                    Intent data = new Intent();
                    data.putExtra("title", title_Edit.getText().toString());
                    data.putExtra("content", content_Edit.getText().toString());
                    setResult(RESULT_OK, data);
                    finish();
                }
            });
            builder.setNegativeButton("Discard", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id)
                {
                    showToast();
                    finish();
                }
            });

            builder.setMessage("Your note is not saved!\n" + "Do you want to save '" + title_Edit.getText().toString() + "'?");
            builder.setTitle("Notice");

            AlertDialog dialog = builder.create();
            dialog.show();
        }
    }

    public void showToast(){
        Toast.makeText(this, "Data isn't saved!", Toast.LENGTH_SHORT).show();
    }
}

Information Adaptor,recyclerView 要求的类之一,里面需要重写3个方法,一个负责创造动态的recyclerView,一个要跟ViewHolder联系起来,设置文本内容,一个显示ArrayList里面有多少元素。

package com.example.multinotes;


import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;

public class InformationAdapter extends RecyclerView.Adapter
{
    private static final String TAG = "InformationAdapter";
    private ArrayList noteList;
    private MainActivity mainAct;

    public InformationAdapter(ArrayList noteList, MainActivity ma) {
        this.noteList = noteList;
        mainAct = ma;
    }

    @Override
    public MyViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
        Log.d(TAG, "onCreateViewHolder: MAKING NEW");
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.information, parent, false);


        itemView.setOnClickListener(mainAct);
        itemView.setOnLongClickListener(mainAct);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {

        Log.d(TAG, "onBindViewHolder: " + position);

        Note note = noteList.get(position);
        holder.title.setText(note.getTitle());
        holder.date.setText(note.getDate());
        String s = note.getContent();
        int len = s.length();
        if(len > 80){
            s = s.substring(0, 80);
            s += "...";
        }
        holder.content.setText(s);

    }

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

}

ViewHolder: 

package com.example.multinotes;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

public class MyViewHolder extends RecyclerView.ViewHolder {

    public TextView title;
    public TextView date;
    public TextView content;

    public MyViewHolder(View view) {
        super(view);
        title = (TextView) view.findViewById(R.id.title);
        date = (TextView) view.findViewById(R.id.date);
        content = (TextView) view.findViewById(R.id.content);
    }
}

 自己建立的Note类,标题内容创建时间,arrayList的内容。

package com.example.multinotes;

import java.util.Date;

public class Note
{
    public String content;
    public String title;
    private String date;

    public Note(String title, String content)
    {
        this.title = title;
        this.content = content;
        date = setDate();
    }

    private String setDate()
    {
        Date date = new Date();
        return date.toString();
    }

    public String getContent() { return content; }

    public String getTitle() { return title; }

    public String getDate() { return date; }

    public String toString(){ return title + date; }
}

版本信息:

package com.example.multinotes;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class VersionActivity extends AppCompatActivity {

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

MainActivity,比较复杂,结合了menu,Jason,start,onActivityResult等等

package com.example.multinotes;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.JsonReader;
import android.util.JsonWriter;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;


public class MainActivity extends AppCompatActivity
        implements View.OnClickListener, View.OnLongClickListener  {

    private ArrayList noteList = new ArrayList<>();
    private RecyclerView recyclerView;
    private InformationAdapter mAdapter;
    private static final int REQUEST_CODE_1 = 1;
    private static final int REQUEST_CODE_2 = 0;
    static int i = 0;
    private int position;

    private static final String TAG = "MainActivity";

    //AsyncTask.
    private class MyAsyncTask extends AsyncTask
    {
        @Override
        protected Void doInBackground(Void... voids) {
            noteList = loadFile();
            return null;
        }
    }

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

        Log.d(TAG, "onCreate: " + i++);
        recyclerView = findViewById(R.id.recycler);
        mAdapter = new InformationAdapter(noteList, this);
        recyclerView.setAdapter(mAdapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        recyclerView.addItemDecoration(new DividerItemDecoration(this,
                DividerItemDecoration.VERTICAL));

        onResult();
        mAdapter.notifyDataSetChanged();
    }

    //Loading Json data by AsyncTask.
    private void onResult() { new MyAsyncTask().execute(); }

    //Save data to Json file.
    @Override
    protected void onPause() {
        saveNote();
        super.onPause();
    }

    //Add a new item to the head of ArrayList.
    private void addItem(Note note)
    {
        noteList.add(0, note);
        mAdapter.notifyDataSetChanged();
    }

    //Remove specific "position"th item form ArrayList.
    private void removeItem(int position)
    {
        noteList.remove(position);
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        String title;
        String content;

        if (requestCode == REQUEST_CODE_1) {
            if (resultCode == RESULT_OK) {
                title = data.getStringExtra("title"); // Get String from EditActivity
                content = data.getStringExtra("content");
                addItem(new Note(title, content)); // Add new item to ArrayList.
            }
            else {
                Log.d(TAG, "onActivityResult: result Code: " + resultCode);
            }
        }
        else if(requestCode == REQUEST_CODE_2)
        {
            if (resultCode == RESULT_OK)
            {

                title = data.getStringExtra("title");
                content = data.getStringExtra("content");
                noteList.get(position).title = title;
                noteList.get(position).content = content;
                mAdapter.notifyDataSetChanged();
            }
        }
        else {
            Log.d(TAG, "onActivityResult: Request Code " + requestCode);
        }
    }

    @Override
    public void onClick(View v)
    {
        //go to another activity, that activity will allow use edit noteList.
        position = recyclerView.getChildAdapterPosition(v);
        Intent intent = new Intent(MainActivity.this, EditActivity.class);
        String temp_title = noteList.get(position).getTitle();
        String temp_content = noteList.get(position).getContent();
        intent.putExtra("title", temp_title);
        intent.putExtra("content", temp_content);
        startActivityForResult(intent, REQUEST_CODE_2);
    }

    @Override
    public boolean onLongClick(View v) {

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        position = recyclerView.getChildAdapterPosition(v);
        //builder.setIcon(R.drawable.icon1);
        builder.setPositiveButton("DELETE", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                //position = mAdapter.getPosition();
                removeItem(position);
            }
        });
        builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
            }
        });

        builder.setMessage("Do you want to delete '"+noteList.get(position).title+"'?");
        builder.setTitle("Warning");

        AlertDialog dialog = builder.create();
        dialog.show();
        return false;
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.action_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        Log.d(TAG, "onOptionsItemSelected: " + i++);
        switch (item.getItemId()) {
            case R.id.version:
                //go to an activity that display version and author information.
                Intent intent1 = new Intent(MainActivity.this, VersionActivity.class);
                startActivity(intent1);
                return true;
            case R.id.addElement:
                //go to another activity, and that activity allows user add a new Note class into noteList.
                Intent intent2 = new Intent(MainActivity.this, EditActivity.class);
                startActivityForResult(intent2, REQUEST_CODE_1);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void saveNote() {

        Log.d(TAG, "saveNote: Saving JSON File");
        try {
            FileOutputStream fos = getApplicationContext().openFileOutput(getString(R.string.file_name), Context.MODE_PRIVATE);

            JsonWriter writer = new JsonWriter(new OutputStreamWriter(fos, getString(R.string.encoding)));
            writer.setIndent("  ");
            writer.beginObject();
            for(int i = 0; i < noteList.size(); i++)
            {
                writer.name("title").value(noteList.get(i).title);
                writer.name("content").value(noteList.get(i).content);
            }
            writer.endObject();
            writer.close();
        } catch (Exception e) {
            e.getStackTrace();
        }
    }

    private ArrayList loadFile() {

        Log.d(TAG, "loadFile: Loading JSON File");
        ArrayList title_holder = new ArrayList<>();
        ArrayList content_holder = new ArrayList<>();
        try {
            InputStream is = getApplicationContext().openFileInput(getString(R.string.file_name));
            JsonReader reader = new JsonReader(new InputStreamReader(is, getString(R.string.encoding)));

            reader.beginObject();
            while (reader.hasNext()) {
                String name = reader.nextName();
                if (name.equals("title")) {
                    title_holder.add(reader.nextString());
                } else if (name.equals("content")) {
                    content_holder.add(reader.nextString());
                } else {
                    reader.skipValue();
                }
            }
            reader.endObject();

        } catch (FileNotFoundException e) {
            Toast.makeText(this, getString(R.string.no_file), Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
        }

        for(int i = 0; i < title_holder.size(); i++)
            noteList.add(new Note(title_holder.get(i), content_holder.get(i)));

        return noteList;
    }
}

activity_edit.xml 




    

    

 activity_main.xml




    

activity_version.xml





    

    

    

information.xml





    

    

    

 action_menu.xml




    
    

action_menu2.xml




    

 

你可能感兴趣的:(个人总结)