Activity组件(Android studio实操相关

1、LayoutInflater 对象:可以用来加载布局文件的对象。

获取方式:getLayoutInflater()方法

LayoutInflater inflater = getLayoutInflater();
//或者
LayoutInflater inflater = LayoutInflater.from(context);

作用:
使用其 inflate(布局文件,父布局root[,boolean attachToRoot]) 方法,返回一个 View对象。

inflater.inflate(R.layout.layout1,null);
inflater.inflate(R.layout.layout2, root,false);
inflater.inflate(R.layout.layout3, root,true);
  1. 在不设置attachToRoot参数的情况下,如果root不为null,attachToRoot参数默认为true。
    2)如果 root 为null,attachToRoot将失去作用,设置任何值都没有意义。
    3)如果 root 不为null,
    attachToRoot设为true,则会给加载的布局文件的指定一个父布局,即root。
    attachToRoot设为false,则会将布局文件最外层的所有layout属性进行设置,当该view被添加到父view当中时,这些layout属性会自动生效。

2、AlertDialog.Builder 对象 :对话框对象。

获取方式:通过new() 方式,构造方法参数为一个context。

AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

其有很多方法,可以用于设置对话框样式:

builder.setIcon(R.drawable.pic)
        .setTitle("用户登录")
        .setMessage("简单对话框")
        .setView(log_view)     		//可以为一个布局文件,也可以为一个ImageView对象
        .setNegativeButton("取消", null)
        .setPositiveButton("登录", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {}
        });
        .setMultiChoiceItems(new String[] {"选项1","选项2","选项3","选项4"}, null, null)
        //设置多选框。后两个参数可以为一个boolean[]数组、一个OnMultiChoiceClickListener监听器     		
        .setSingleChoiceItems(new String[] {"选项1","选项2","选项3","选项4"}, null, null)
        .setItems(new String[] {"列表项1","列表项2","列表项3"}, null)
        //设置列表项,后一个参数可为DialogInterface.OnClickListener() 监听器
builder.create().show();

3 、ArrayAdaptter、SimpleAdapter、BaseAdapter适配器展示列表数据

tips:格式单一的数据 ArrayAdapter、格式多样的数据SimpleAdapter 、BaseAdapter(后者灵活度更高,需要重写适配器类,需要手动将数据放进布局控件中)。

相同点,这三者都是用来适配数据项跟 listView的,将每一项分别作为一行。
因此,我们需要先在整体布局中设计一个listView控件,然后再给适配器们单独设置每行数据的布局。

(1)ArrayAdapter的一种使用方式:

a)编写好布局之后 ,将数据放入一个泛型 list 中;
b)new 一个适配器ArrayAdapter,写入构造方法的四个参数【 context 、每一项数据的布局的文件、每一项对应的布局文件中的控件、数据】;
c)获取主布局的listVew控件,给其 setAdapter,参数中传入适配器;

ps:还可以用 listView 控件的 setOnItemClickListener()方法设置一个AdapterView.OnItemClickListener()监听器。

List<String> data = new ArrayList<>();
data.add("北京");
data.add("上海");
data.add("广州");
final ArrayAdapter<String> adapter1 = new ArrayAdapter<>(
        MainActivity.this,
        R.layout.itemlayout1,
        R.id.textView,
        data
);
listView.setAdapter(adapter1);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override//重写onItemClick方法
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {}
}

(2)SimpleAdapter的一种使用方式:

a)同样定义一个泛型 List,类型为 Map。先把每一项数据的各值以 key、value方式放入Map 、再把Map 放入List。
b)同样 new 一个SimpleAdapter,并给构造方法传参【context, 数据,每一项数据的布局的文件,一项数据的 key 数组,每个key 的数据对应的布局的文件的控件】;
c)同样是给listView 设置适配器;

String[] food = new String[]{"北京烤鸭","上海小笼包","广州拉肠"};
int[] images = {R.drawable.duck, R.drawable.baozi, R.drawable.lachang};
List<Map<String, Object>> list_map = new ArrayList<Map<String, Object>>();
for (int i = 0; i<3; i++){
    Map<String, Object> items = new HashMap<String, Object>();
    items.put("image", images[i]);
    items.put("food", food[i]);
    list_map.add(items);
}
final SimpleAdapter adapter2 = new SimpleAdapter(
        MainActivity.this,
        list_map,
        R.layout.itemlayout2,
        new String[]{"image", "food"},
        new int[]{R.id.imageView2, R.id.textView2}
);
listView.setAdapter(adapter2);

(3)BaseAdapter的一种使用方式:

a)定义一个实体类 ,存放每一项的数据,并写入set/get方法;
b)同样定义一个泛型List,类型为自己定义的实体类类型,并把数据都放进去 ;
c)编写一个继承抽象类BaseAdapter的类,完善其抽象方法;
(如果有些方法用不到,可以把自己也定义为抽象类,就不用实现全部了吧?)
重点是在其setView()方法中,找到控件,然后把给其setText为数据项;
ps:为提高效率 ,第一次加载视图时 ,可以定义一个实体类把控件都保存到convertView对象
中;后面每一次可以先判断convertView是否为空 ,若不为空就可以直接在convertView取。
d)同样new一个刚刚编写的适配器类,传参只需要 【context,数据 】
e)同样是给listView 设置适配器 。

//实体类
public class Item {
    private int itemImage;
    private String itemTitle;
    private String itemContent;

    public Item(int itemImage, String itemTitle, String itemContent){
        this.itemImage = itemImage;
        this.itemTitle = itemTitle;
        this.itemContent = itemContent;
    }
    //省略getter/setter方法
    }
//自己编写的适配器类
public class TestAdapter extends BaseAdapter {
    private List<Item> list;
    private LayoutInflater layoutInflater;

    public TestAdapter(Context context, List<Item> list){
        layoutInflater = LayoutInflater.from(context);
        this.list = list;
    }

    public int getCount(){
        return list.size();
    }

    public Object getItem(int position){
        return list.get(position);
    }

    public View getView(int position, View convertView, ViewGroup parent){
        ViewHolder viewHolder;
        Item item = list.get(position);

        if(convertView == null){
            convertView = layoutInflater.inflate(R.layout.itemlayout3, null);
            viewHolder = new ViewHolder();
            viewHolder.imageView = convertView.findViewById(R.id.imageView3);
            viewHolder.title = convertView.findViewById(R.id.title);
            viewHolder.content = convertView.findViewById(R.id.content);
            convertView.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.title.setText(item.getItemTitle());
        viewHolder.content.setText(item.getItemContent());
        viewHolder.imageView.setImageResource(item.getItemImage());

        return convertView;
    }
    public static class ViewHolder{
        public ImageView imageView;
        public TextView title;
        public TextView content;
    }
}
//主活动
List<Item> list = new ArrayList<>();
list.add(new Item(R.drawable.duck, "北京烤鸭", "热门评价:吃过最好吃的烤鸭!"));
list.add(new Item(R.drawable.baozi, "上海小笼包", "热门评价:汤汁多!"));
list.add(new Item(R.drawable.lachang, "广州拉肠", "热门评价:真香!"));
final TestAdapter adapter3 = new TestAdapter(MainActivity.this,list);
listView.setAdapter(adapter3);

在这里插入图片描述

4、导航栏菜单设置 toolbar

1)getSupportActionBar().hide(); 将原始导航栏隐藏;
2)在布局文件中定义一个 toolbar,并获取他;
3)新建一个 menu资源文件,并写入需要的menu item;
4)使用 toolbar 的inflateMenu(menu资源) 方法把菜单加载进去;
5)可以给toolbar 设置一个点击监听器。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getSupportActionBar().hide();
    Toolbar toolbar = findViewById(R.id.toolbar);
    toolbar.inflateMenu(R.menu.menu_option);
    toolbar.setOnMenuItemClickListener(new MyMenuItemClickListener());
}
private class MyMenuItemClickListener implements Toolbar.OnMenuItemClickListener{
        @Override
        public boolean onMenuItemClick(MenuItem item) {
    	//自定义
    	}
}

在这里插入图片描述

5、fragment动态加载

上面适配器的栗子,我们使用了通过判断button的点击监听来分别设计相应的 listView。

现在,我们通过使用fragment ,就可以实现通过button 的监听来动态改变页面 的数据。(只是数据 ,布局不改变)

一个简单栗子:

a)编写实体类BookContent,并在其写入内部类Book以及定义两个静态变量 ITEM(存入三个Book对象的列表)、ITEM_MAP(存入三个Book对象及id的Map);

b)编写类 BookListFragment继承 ListFragment类,在其中定义一个与主Activity 通信的接口,写一个监听方法;
重写父类onCreate 方法,在其中写入用 setListAdapter设置一个 ArrayAdapter适配器 ,适配器的数据为 书信息的列表ITEM,布局直接使用原生布局和原生控件;
重写onAttach方法 ,判断主Activity是否继承通信接口;
重写 onDetach方法,将接口置空;
重写onListItemClick方法 ,添加通信接口的监听处理;

c)编写主布局文件为左右布局,写一个fragment,指定name为刚刚定义的BookListFragment及其包名,与程序连接,展现书信息列表;再写一个framelayout控件,用于动态加载数据 ;
再编写一个布局文件,用于设置framelayout的布局;

d)编写主 Activity,实现与BookListFragment的通信接口,并实现其方法;该方法中,将BookListFragment传过来的id放到 Bundle中并传给 BookDetailFragment类;然后获取fragment管理器,开始事物,即,用 BookDetailFragment类对象取代主布局中的 framelayout;

e)编写 类BookDetailFragment类 ,继承Fragment;
在类中,获取主 Activity传来的参数id,检查数据中是否存在此id,若有 ,则在 onCreateView方法中获取数据展示布局文件并给各控件设置值。

//书本实体类
public class BookContent {
    public static class Book{
        public Integer id;
        public String title;
        public String desc;
        public Book(int id, String title, String desc){
            this.id = id;
            this.title = title;
            this.desc = desc;
        }

        @Override
        public String toString() {
            return title;
        }
    }
    public static List<Book> ITEM = new ArrayList<Book>();
    public static Map<Integer, Book> ITEM_MAP = new HashMap<Integer, Book>();
    static {
        addItem(new Book(1,"数据结构","了解Java基础"));
        addItem(new Book(2,"javaWeb","了解Web开发"));
        addItem(new Book(3,"高等数学","编程必备数学基础"));
    }
    private static void addItem(Book book){
        ITEM.add(book);
        ITEM_MAP.put(book.id,book);
    }

}
public class BookListFragment extends ListFragment {
    public interface Callbacks{
        public void onItemSelected(Integer id);
    }
    private Callbacks mCallbacks;
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setListAdapter(new ArrayAdapter<BookContent.Book>(getActivity(),
                //R.layout.simple_list_item_activated_1:原生布局,代表只有单行text
                android.R.layout.simple_list_item_activated_1,android.R.id.text1,
                BookContent.ITEM)
        );
    }
    public void onAttach(Activity activity){
        super.onAttach(activity);
        if(! (activity instanceof Callbacks)){
            throw new IllegalStateException("BookListFragment所在的activity必须实现Callbacks接口!");
        }
        mCallbacks = (Callbacks)activity;
    }

    public void onDetach(){
        super.onDetach();
        mCallbacks = null;
    }
    public void onListItemClick(ListView listView, View view, int position, long id){
        super.onListItemClick(listView, view, position, id);
        mCallbacks.onItemSelected(BookContent.ITEM.get(position).id);
    }
}
public class MainActivity extends AppCompatActivity implements BookListFragment.Callbacks{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void onItemSelected(Integer id){
        Bundle bundle = new Bundle();
        bundle.putInt(BookDetailFragment.ITEM_ID, id);
        BookDetailFragment fragment = new BookDetailFragment();
        fragment.setArguments(bundle);
        getFragmentManager().beginTransaction()
                .replace(R.id.book_detail_container, fragment)
                .addToBackStack(null)
                .commit();
    }
}
public class BookDetailFragment extends Fragment {
    public static final String ITEM_ID = "item_id";
    BookContent.Book book;
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        if(getArguments().containsKey(ITEM_ID)){
            book = BookContent.ITEM_MAP.get(getArguments().getInt(ITEM_ID));
        }
    }

    public View onCreateView(LayoutInflater infater,  ViewGroup container, Bundle savedInstanceState){
        View rootView = infater.inflate(R.layout.fragment_book_detail, container,false);
        if(book != null){
            ((TextView)rootView.findViewById(R.id.book_title)).setText(book.title);
            ((TextView)rootView.findViewById(R.id.book_desc)).setText(book.desc);
        }
        return rootView;
    }
}

在这里插入图片描述

6 、打电话

(1)直接调用系统电话 ,此时无需权限授予 。

只需给intent 添加个动作,然后startActivity(intent) 即可;
ps:设置默认号码 ,可以给intent setData。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_DIAL);
        intent.setData(Uri.parse("tel:13016033333"));
        startActivity(intent);
    }
}

(2)在程序内拨打电话 ,需要权限 。

a)先在清单里申请权限:

b)在onCreate时 ,需要先判断用 AtivityCompat类的 checkSelfPermission方法判断权限是否已获得。若是 ,直接执行拨打电话的代码 ;若否 ,则要用AtivityCompat类的 requestPermission方法再次请求 ;
然后 ,在onRequestPermissionResult 方法中再次判断权限是否已获得。若是,执行打电话代码 ;若否,提示无权限 ,销毁自己 ;
c)编写打电话代码 ,获取输入电话控件的值 ,给intent设置动作以及值;给拨号按钮设置监听事件 。

//程序内编写电话功能
public class MainActivity extends AppCompatActivity {
    EditText editText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission
        .CALL_PHONE) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{
                    Manifest.permission.CALL_PHONE}, 1);
        }else{
            fun();
        }
    }

    public void fun(){
        editText = findViewById(R.id.number);
        findViewById(R.id.call).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction(intent.ACTION_CALL);
                intent.setData(Uri.parse("tel:" + editText.getText().toString()));
                startActivity(intent);
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case 1:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    fun();
                }else{
                    Toast.makeText(this,"无电话权限",Toast.LENGTH_SHORT).show();
                    finish();
                }
        }
    }
}

在这里插入图片描述

7 、发短信

(1)跟打电话一样 ,直接调用系统短信 ,无需权限,给intent设个动作就好了:

public class MainActivity extends AppCompatActivity {
//调用系统发短信功能
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent();
        intent.setAction(intent.ACTION_SENDTO);
        intent.setData(Uri.parse("sms:10086?body=短信程序设计"));
        startActivity(intent);
    }
}

(2)在程序内发送短信 ,需要先在清单申请权限:

a)同样是判断权限是否已获得动作 ;不同的是,这此处有多个权限 ,可以把他们先放进数组里,用循环判断 ;另外再拿一个列表来放没获得的权限 ,最后把这个列表转成数组再次判断;
b)获得权限后,执行发短信代码:分三步走:先用 getSmsManage获得短信管理员 ;再让管理员 divideMessage把短信切成合适长度,放进一个列表里面;最后逐个发送 sendTextMessage。

//程序内实现发短信
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String[] permissions = new String[]{
                "android.permission.SEND_SMS",
                "android.permission.READ_PHONE_STATE"
        };
        ArrayList<String> mPermission = new ArrayList();
        for(int i=0; i<permissions.length; i++) {
            if (ActivityCompat.checkSelfPermission(MainActivity.this, permissions[i]) !=
                    PackageManager.PERMISSION_GRANTED){
                mPermission.add(permissions[i]);
            }
        }
        if(mPermission.isEmpty()){
            fun();
        }else{
            String[] needPermission = mPermission.toArray(new String[mPermission.size()]);
            ActivityCompat.requestPermissions(this, needPermission, 1);
        }
    }

    public void fun(){
        findViewById(R.id.sendBtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText recevier = findViewById(R.id.recevierNum);
                EditText centent = findViewById(R.id.smsContent);
                SmsManager smsManager =SmsManager.getDefault();
                List<String> list = smsManager.divideMessage(centent.getText().toString());
                for(String sms:list){
                    smsManager.sendTextMessage(recevier.getText().toString(), null,
                            sms,null,null);
                }
            }
        });
    }

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case 1:
                for(int i=0; i<permissions.length; i++){
                    if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
                        Toast.makeText(this,"权限不足",Toast.LENGTH_SHORT).show();
                        finish();
                    }
                }fun();

        }
    }
}

8 、拍照保存

a)同样 ,先申请拍照权限:

b)同样 ,检查权限是否获得 ,若无进行再处理;

c)编写 执行拍照的方法 ,即给设置一个拍照 intent ,然后 startActivityForResult;

d)编写 onActivityResult 方法,在内部存储中新建一个放照片的文件夹;用一个位图对象去接收intent 中的数据;将位图压缩后的数据放在一个放在文件夹下的输出流中 ;把输出流缓冲区的东西真正的放进内存 ;并用 photo对象把位图显示。

public class MainActivity extends AppCompatActivity {
    ImageView photo;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
                PackageManager.PERMISSION_GRANTED){
            fun();
        }else{
            ActivityCompat.requestPermissions(MainActivity.this,new String[]{
                    Manifest.permission.READ_EXTERNAL_STORAGE
            }, 1);
        }
    }

    void fun(){
        photo = findViewById(R.id.photo);
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(intent, 1);
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data){
        super.onActivityResult(requestCode,resultCode,data);
        String basePath = Environment.getExternalStorageDirectory().getPath();
        String filePath = basePath + "/testImage";
        if(requestCode ==1 ){
            if(resultCode == RESULT_OK);{
                Bundle bundle = data.getExtras();
                Bitmap bitmap = (Bitmap) bundle.get("data");
                FileOutputStream fos = null;
                File file = new File(filePath);
                file.mkdir();
                String fileName = filePath + "/4-6.jpg";
                try{
                    fos = new FileOutputStream(fileName);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    try {
                        fos.flush();
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                    }photo.setImageBitmap(bitmap);
                }
            }
        }



    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case 1:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    fun();
                }else{
                    Toast.makeText(this,"没有SD卡权限",Toast.LENGTH_SHORT).show();
                    finish();
                }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值