安卓 Android之开发简单小应用(三)

一、简述

    一个简单的txt文本编辑器。

    工程打包:链接:https://pan.baidu.com/s/1CsszQVde5QAiQVMu2fC63w 密码:qyjt

二、效果



三、工程结构


四、源文件

TxtReader.java文件

package com.mypackage.MyNotepad;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import com.ostrichmyself.txtReader.R;


import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.text.InputFilter;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.TextView;
import android.widget.Toast;

public class TxtReader extends Activity implements OnClickListener {
    /** Called when the activity is first created. */
	private String filePath = "";//保存文件的绝对路径
	private String fileName = "";//文件名
	private static final String defaultCode = "UTF8";//默认编码
    @SuppressLint("NewApi") @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);//设置为没有标题栏,自定义一个标签作为标题
        setContentView(R.layout.main);//设置布局
       
        //获取控件对象,并监听点击事件
        Button fileOpenBtn = (Button)findViewById(R.id.btn_open);
        fileOpenBtn.setOnClickListener(new OpenFileAction());
        
        Button btnexit = (Button)findViewById(R.id.btn_exit);
        btnexit.setOnClickListener(this);
        
        Button btnsave = (Button)findViewById(R.id.btn_save);
        btnsave.setOnClickListener(this);
        
        Button btnsaveas = (Button)findViewById(R.id.btn_saveas);
        btnsaveas.setOnClickListener(this);
        
        Button btnfind = (Button)findViewById(R.id.btn_find);
        btnfind.setOnClickListener(this);
        
        Button btnnew = (Button)findViewById(R.id.btn_new);
        btnnew.setOnClickListener(this);
//        
//      
    }
    
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = this.getMenuInflater();
		inflater.inflate(R.menu.menu, menu);
		return true;
	}


	
    @Override    //子页面返回时执行
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	if(requestCode == 1 && resultCode == 1){//有多个页面时根据请求码和结果码判断是哪一个子页面结束返回,并相应的做出响应
    		try {
    			Bundle bunde=data.getExtras();//获取数据束
    			filePath = bunde.getString("path");//类似于键值对,根据键"path"获取对应的值(子页面传回来的数据)
    			fileName = filePath.substring(filePath.lastIndexOf("/")+1,filePath.length());//根据绝对路径得到文件名,(用来设置标题)
    			TextView tvtitle = (TextView)findViewById(R.id.tv_title);//获取便签对象,作为标题
    			tvtitle.setText(fileName+"-我的记事本");//设置文本
    			
    			EditText tv = (EditText) findViewById(R.id.edt_contents);//获取到多行编辑框
    			String fileContent = getStringFromFile(defaultCode);//获取到文件内容
    			tv.setText(fileContent);//将编辑框的内容设置为文件内容
    			
    		} catch (Exception e)
    		{
    			Toast.makeText(this, "获取数据异常",Toast.LENGTH_SHORT).show();
    		}
    	}
		
	}

	
	public String getStringFromFile(String code)//按照一定的编码格式读取txt文件
	{
		try {
			StringBuffer sBuffer = new StringBuffer();//用来存放文件内容
			FileInputStream fInputStream = new FileInputStream(filePath);//根据绝对路径创建数据流
			InputStreamReader inputStreamReader = new InputStreamReader(fInputStream, code);
			BufferedReader in = new BufferedReader(inputStreamReader);
			if(!new File(filePath).exists())//如果文件不存在
			{
				in.close();//关闭流
				return null;//直接返回
			}
			while (in.ready()) {
				sBuffer.append(in.readLine() + "\n");//一行一行的读取,并追加到sBuffer中
			}
			in.close();//关闭流
			return sBuffer.toString();//返回文件内容
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	class OpenFileAction implements OnClickListener
    {

		public void onClick(View v) {//这是另外一种方式实现监听
			//"打开"按钮的监听事件处理,跳转到文件列表
			Intent in = new Intent(TxtReader.this, ListAllFileActivity.class);
			startActivityForResult(in, 1);//设置请求码为1
		}
    	
    }

	@SuppressLint("NewApi") 
	@Override
	public void onClick(View arg) {//监听事件处理
		switch (arg.getId()) 
		{
			case R.id.btn_new://新建按钮
				EditText tv = (EditText) findViewById(R.id.edt_contents);//获取到文本编辑框对象
				tv.setText("");//清空内容
				filePath = "";//清空路径
				fileName = "";//清空文件名
				TextView tvtitle = (TextView)findViewById(R.id.tv_title);//获取到标题标签
				tvtitle.setText("未命名.txt-我的记事本");//设置文本
				break;
        	case R.id.btn_save://保存按钮
        		if(fileName.isEmpty())//文件名为空,说明是新建文件(未命名)
        		{
        			//弹出对话框,让用户输入文件名
        			AlertDialog.Builder builderExit = new AlertDialog.Builder(this);
            		builderExit.setTitle("保存");  //对话框标题
            		builderExit.setMessage("请输入文件名!");//对话框提示信息
            		final EditText edtname = new EditText(this);//创建一个输入框对象
        	        edtname.setSingleLine();//设置为单行输入
        	        edtname.setText("未命名.txt");//设置文本
        	        edtname.setSelection(0, 3);//选中文本的第0开始的3个字符(就是选中"未命名"3个字符)
        	        edtname.setFilters(new InputFilter[]{
        	        		new InputFilter.LengthFilter(64)//设置输入最大长度
        	        });
        	        builderExit.setView(edtname);//将输入框添加到对话框
            		builderExit.setNegativeButton("取消",null); //添加取消按钮
            		//添加确定按钮,并且添加单击事件处理
            		builderExit.setPositiveButton("确定", new DialogInterface.OnClickListener() {  
        	            @Override  
        	            public void onClick(DialogInterface dialog, int which) { 
        	            	String name = edtname.getText().toString().trim();//获取输入框的文本内容,并去掉前后空格
        	            	if(!(name.isEmpty()))//如果输入的文件名不为空
        	            	{
        	            		if(!name.endsWith(".txt"))//文件名没有以".txt"结尾
        	            		{
        	            			name += ".txt";//在结尾处添加".txt"
        	            		}
        	            		fileName = name;//更新为当前文件名
        	            		//获取文本编辑框对象
        	            		EditText edtcontent = (EditText) findViewById(R.id.edt_contents);
        	            		//将文本编辑框内容保存到文件
        	            		boolean b = Save(name,edtcontent.getText().toString(),true);
        	            		if(b) 
        	            		{
        	            			TextView tvtitle = (TextView)findViewById(R.id.tv_title);//获取到标题标签
            	    				tvtitle.setText(fileName+"-我的记事本");//设置文本
            	    				//弹出小黑框提示
        	            			Toast.makeText(TxtReader.this,"已保存",Toast.LENGTH_SHORT).show();
        	            		}
        	            		
        	            	}
        	            	else//文件名为空
        	            	{
        	            		//提示
        	            		Toast.makeText(TxtReader.this,"文件名不能为空",Toast.LENGTH_SHORT).show();
        	            	}
        	            	
        	            }  
        	        });  
            		builderExit.show();//弹出保存对话框
        		}
        		else //文件名不为空,说明是打开的文件,或者是已经保存过一次的文件
        		{
        			if(!fileName.endsWith(".txt"))//文件名不以".txt"结尾
            		{
        				fileName += ".txt";//在结尾加上".txt"
            		}
        			//获取文本输入框对象
        			EditText edtcontent = (EditText) findViewById(R.id.edt_contents);
        			//获取文本输入框的内容
        			String txt = edtcontent.getText().toString();
        			//System.out.println(txt);
        			//覆盖保存到文件中,
            		boolean b = Save(fileName,txt,false);
            		//提示保存成功
            		if(b)Toast.makeText(TxtReader.this,"已保存",Toast.LENGTH_SHORT).show();
            		
        		}
        		break;
        	case R.id.btn_saveas://另存为按钮
        		if(true)
        		{
        			//弹出文件两寸为对话框
        			AlertDialog.Builder builderExit = new AlertDialog.Builder(this);
            		builderExit.setTitle("另存为");//设置标题  
            		builderExit.setMessage("请输入文件名!");//设置提示信息
            		final EditText edtname = new EditText(this);//创建文本输入框对象
        	        edtname.setSingleLine();//设置为单行输入
        	        if(filePath.isEmpty())//如果原来文件名为空,说明是新建文件
        	        {
        	        	edtname.setText("未命名.txt");//设置文本(初始文件名)
        	        	edtname.setSelection(0, 3);//选中"未命名"3个子符
        	        }
        	        else //如果原来文件名不为空,说明是不是新建文件
        	        {
        	        	//确保文件名是以".txt"结尾的
        	        	if(!fileName.endsWith(".txt"))
        	        	{
        	        		fileName += ".txt";
        	        	}
        	        	edtname.setText(fileName);//将文本框初始文本为原来的文件名
        	        	int top = fileName.indexOf(".txt")+1;
        	        	edtname.setSelection(0, top);//选中原来的文件名
        	        }
        	        edtname.setFilters(new InputFilter[]{
        	        		new InputFilter.LengthFilter(64)//设置最大文件名长度
        	        });
        	        builderExit.setView(edtname);//将编辑框添加到另存为对话框
            		builderExit.setNegativeButton("取消",null); //添加取消按钮
            		//添加确定按钮,并监听点击事件
            		builderExit.setPositiveButton("确定", new DialogInterface.OnClickListener() {  
        	            @Override  
        	            public void onClick(DialogInterface dialog, int which) { 
        	            	String name = edtname.getText().toString().trim();//获取输入框的内容并去掉两端的空格
        	            	if(!(name.isEmpty()))//如果文件名不为空
        	            	{
        	            		//确保文件名以".txt"结尾
        	            		if(!name.endsWith(".txt"))
        	            		{
        	            			name += ".txt";
        	            		}
        	            		fileName = name;//设置当前文件名
        	            		//获取文本输入框对象
        	            		EditText edtcontent = (EditText) findViewById(R.id.edt_contents);
        	            		//将文件内容覆盖保存
        	            		boolean b = Save(name,edtcontent.getText().toString(),false);
        	            		//提示保存成功
        	            		if(b) Toast.makeText(TxtReader.this,"已保存",Toast.LENGTH_SHORT).show();
        	            		
        	            	}
        	            	else//文件名为空
        	            	{
        	            		Toast.makeText(TxtReader.this,"文件名不能为空",Toast.LENGTH_SHORT).show();
        	            	}
        	            	
        	            }  
        	        });  
            		builderExit.show();//弹出另存为对话框
        		}
        		break;
        	case R.id.btn_find://查找按钮
        		//查找、替换对话框
        		AlertDialog.Builder builder = new AlertDialog.Builder(TxtReader.this);
    			builder.setTitle("查找/替换"); //设置标题
    			//创建一个网格布局
    	        GridLayout grid = new GridLayout(TxtReader.this);
    	        grid.setColumnCount(2);//设置列数
    	      
    	        //创建替换为标签
    	        TextView viewrpl = new TextView(TxtReader.this);
    	        viewrpl.setText("替换为:");//设置文本
    	        //创建替换文本输入框
    	        final EditText edtrpl = new EditText(TxtReader.this);
    	        edtrpl.setSingleLine();//设置为单行
    	        edtrpl.setHeight(45);//设置高度
    	        edtrpl.setPadding(3, 0, 3, 0);//设置内边距,左上右下
    	        edtrpl.setHint("请输入要替换为的字符");//设置初始文本(获取焦点是次文本消失)
    	        edtrpl.setFilters(new InputFilter[]{
    	        		new InputFilter.LengthFilter(64)//设置最大长度
    	        });
    	       
    	       
    	        grid.addView(viewrpl, 0);//将替换为标签添加到网格布局的第0列
    	        grid.addView(edtrpl, 1);//将替换为输入框添加到网格布局的第1列
    	        
    	        //创建查找标签
    	        TextView viewfind = new TextView(TxtReader.this);
    	        viewfind.setText("查找:");//设置文本
    	        //创建查找输入框
    	        final EditText edtfind = new EditText(TxtReader.this);
    	        edtfind.setSingleLine();//设置为单行
    	        edtfind.setHeight(45);//设置高度
    	        edtfind.setPadding(3, 0, 3, 0);//设置内边距
    	        edtfind.setHint("请输入要查找的字符");//设置初始字符
    	        edtfind.setFilters(new InputFilter[]{
    	        		new InputFilter.LengthFilter(64)//设置最大长度
    	        });
    	        
    	        grid.addView(viewfind, 0);//将查找标签添加到网格布局的第0列
    	        grid.addView(edtfind, 1);//将查找输入框添加到网格布局的第1列
    	        
    	        builder.setView(grid);//将网格布局添加到对话框
    	        builder.setNegativeButton("取消",null); //添加取消按钮
    	        //添加查找按钮并监听点击事件
    	        builder.setNeutralButton("查找", new DialogInterface.OnClickListener() {  
    	            @Override  
    	            public void onClick(DialogInterface dialog, int which) {
    	            	String findStr = edtfind.getText().toString();//获取到要查找的文本
    	            	if(findStr.isEmpty())//为空,什么都不做
    	            	{
    	            		
    	            	}
    	            	else//不为空
    	            	{
    	            		//获取文本编辑框对象
    	            		EditText edtcontent = (EditText) findViewById(R.id.edt_contents);
    	            		int start = -1;//选中文本的开始索引
    	            		//在全部内容中查找目标,并记下找到的开始位置
    	            		start = edtcontent.getText().toString().indexOf(findStr);
    	            		if(start != -1)//已经找到
    	            		{
    	            			int stop = start+findStr.length();//选中文本的结束索引
        	            		edtcontent.setSelection(start, stop);//将找到的文本选中
        	            		//提示找到
        	            		Toast.makeText(TxtReader.this,"已找到!",Toast.LENGTH_SHORT).show();
    	            		}
    	            		else//未找到
    	            		{
    	            			Toast.makeText(TxtReader.this,"未找到!",Toast.LENGTH_SHORT).show();
    	            		}
    	            	}
    	            }  
    	        });
    	        //添加替换按钮
    	        builder.setPositiveButton("替换", new DialogInterface.OnClickListener() {  
    	            @Override  
    	            public void onClick(DialogInterface dialog, int which) {  
    	            		String rplstr = edtrpl.getText().toString();//获取到要替换为的文本
    	            		
    		            	Toast.makeText(TxtReader.this,"替换成功!",Toast.LENGTH_SHORT).show();  
    	            	
    	            }  
    	        });  
    	        builder.show(); //弹出对话框
        		break;
        	case R.id.btn_exit://退出按钮
        		//退出确认对话框
        		AlertDialog.Builder builderExit = new AlertDialog.Builder(this);
        		builderExit.setTitle("退出");  //标题
        		builderExit.setMessage("您确定退出吗?");//提示信息
        		builderExit.setNegativeButton("取消",null);//添加取消按钮
        		//添加确定按钮
        		builderExit.setPositiveButton("确定", new DialogInterface.OnClickListener() {  
    	            @Override  
    	            public void onClick(DialogInterface dialog, int which) {  
    	            	finish();//关闭页面
    	            }  
    	        });  
        		builderExit.show();
        		break;
		}
	}
	//保存到文件         filename:文件名     content:内容       isAppend:是否追加,(否则覆盖)
	public static boolean Save(String filename,String content,boolean isAppend) 
	{  
		
        //在文本文本中追加内容 
		String sdCardDir =Environment.getExternalStorageDirectory().getAbsolutePath();
		
		File file = new File(sdCardDir,filename);
		//System.out.println(sdCardDir);
		BufferedWriter out = null;  
        try {
        	if(!file.exists())//文件不存在
        	{
        		file.createNewFile();//创建新文件
        	}
        	FileOutputStream outStream = new FileOutputStream(file,isAppend);
        	outStream.write(content.getBytes());//写入文件
        	outStream.close();//关闭流
            System.out.println("save success!");
            return true;
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                if(out != null){  
                    out.close();  
                }  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }
		return false;  
    } 
}

ListAllFileActivity.java文件

package com.mypackage.MyNotepad;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.ostrichmyself.txtReader.R;

import android.annotation.SuppressLint;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;

/*展现全部文件的Activity*/
public class ListAllFileActivity extends ListActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.filelist);//设置布局
		//初始化文件列表
		File path = android.os.Environment.getExternalStorageDirectory();
		File[] f = path.listFiles();
		fill(f);
	}
	
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {//菜单
		MenuInflater inflater = this.getMenuInflater();
		inflater.inflate(R.menu.menu, menu);
		
		return true;
	}

	
	@Override      //选项点击事件
	protected void onListItemClick(ListView l, View v, int position, long id) {
		
		//bundle = new Bundle();
		File file = fileNameList.get(position);
		if (file.isDirectory())//如果是文件夹,则进入
		{
			File[] f = file.listFiles();
			fill(f);
		}
		else //如果是文件
		{
			//将选中的文件的绝对路径返回给主页面
			Intent intent = new Intent(ListAllFileActivity.this, TxtReader.class);
			//bundle.putString(fileNameKey, file.getAbsolutePath());
			intent.putExtra("path",file.getAbsolutePath());
        	setResult(1, intent);//设置返回码为1
        	finish();
		}
	}
	

	// 读取文件列表,并设置listview
	private void fill(File[] files) {
		fileNameList = new ArrayList<File>();
		for (File file : files) {
			if (isValidFileOrDir(file)) {
				fileNameList.add(file);
			}
		}
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fileToStrArr(fileNameList));
		setListAdapter(adapter);
	}
	
	/*检查是否为合法的文件名,或者是否为路径*/
	@SuppressLint("DefaultLocale") private boolean isValidFileOrDir(File file)
	{
		if (file.isDirectory()) {
			return true;
		}
		else {
			String fileName = file.getName().toLowerCase();
			if (fileName.endsWith(".txt")) {
				return true;
			}
		}
		return false;
	}
	

	private String[] fileToStrArr(List<File> fl)
	{
		ArrayList<String> fnList = new ArrayList<String>();
		for (int i = 0; i < fl.size(); i++) {
			String nameString = fl.get(i).getName();
			fnList.add(nameString);
		}
		return fnList.toArray(new String[0]);
	}
	
	
	/*文件列表*/
	private List<File> fileNameList;

}

五、总结

1、替换功能尚未完成。

2、细节有待完善,比如推出前判断文件是否已经保存了。

3、打开文件列表部分参考的是开源代码,此部分代码有待深入学习。

4、……有待完善!

猜你喜欢

转载自blog.csdn.net/nanfeibuyi/article/details/80793128