【移动应用开发】--常见组件应用代码

发布于:2025-09-02 ⋅ 阅读:(20) ⋅ 点赞:(0)

实验1:

1、两个activity,利用intent进行通信。

  1. 不要返回的结果

startActivity(intent);

  1. 要返回的结果

原:启动intent的方式改变。同时为了 对返回的结果做处理,要重写某个方法(该方法体第一句先super)。

新:new一个intent(this.,旧类)。先putExtra放数据,再setResult,注意这个方法有两个参数(状态码,intent对象)。

销毁页面用finish()

注意:

  1. intent设置启动某个类时,一定带上后缀.class
  2. new一个intent对象不代表启动一个新类,start才会真正的打开
  3. finish销毁后,原界面上的数据还在。但start后,原界面数据就不在了。涉及launchmode

2、字符串和数字之间的转换

Double num=Double.parseDouble();

String s=String.format(“%.2f”,num);

实验2:

1、列表里实现图片和文字

(1)MainActivity.java

package com.example.test;

public class MainActivity extends AppCompatActivity {

private ListView list;  

@Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);  

        list = findViewById(R.id.ls1);  

        String[] data = {"数据结构", "计算机网络", "移动开发"};  // 定义要显示的文字

        int[] imageIds = {

                R.drawable.dsg,     

                R.drawable.jw,      

                R.drawable.ydkf     

        };  // 对应的图片资源(你要把这些图片放到 res/drawable/ 文件夹)

        MyAdapter adapter = new MyAdapter(this, data, imageIds);  // 创建自定义适配器

        list.setAdapter(adapter);  // 设置适配器给 ListView

    }

}

(2)MyAdapter.java

package com.example.test;

public class MyAdapter extends BaseAdapter {

    private Context context;      // 上下文,用于加载布局

    private String[] titles;      // 要显示的文字数组

    private int[] images;         // 对应的图片资源 ID 数组

    public MyAdapter(Context context, String[] titles, int[] images) {  // 构造方法,传入文字和图片数组

        this.context = context;  

        this.titles = titles;    

        this.images = images;    }

    @Override

    public int getCount() {  // 返回列表项个数

        return titles.length;}

    @Override

    public Object getItem(int i) {  // 返回某一项的文字

        return titles[i];}

    @Override

    public long getItemId(int i) {  // 返回某一项的 ID(这里用下标)

        return i;}

    static class ViewHolder {  // 创建一个 ViewHolder 类用于缓存视图,提高性能

        ImageView img;  // 图片控件

        TextView t1;    // 文字控件}

    @Override

    public View getView(int i, View convertView, ViewGroup parent) {  // 创建/复用视图,并绑定数据

        ViewHolder holder;  // 定义 ViewHolder 对象

        if (convertView == null) {  // 如果没有可复用的视图,就创建一个新的

            convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);  // 加载布局

            holder = new ViewHolder();  // 创建 ViewHolder

            holder.img = convertView.findViewById(R.id.I1);  // 获取图片控件

            holder.t1 = convertView.findViewById(R.id.t1);   // 获取文字控件

            convertView.setTag(holder);  // 保存 ViewHolder 到 View 中

        } else {

            holder = (ViewHolder) convertView.getTag();  // 复用旧视图

        }

        holder.t1.setText(titles[i]);  // 设置文字

        holder.img.setImageResource(images[i]);  // 设置图片

        return convertView;  // 返回最终的视图

    }}

(3)两个布局文件。activity_main例放ListView控件,另一个xml控件代表每一项的布局方式,此处就是一个ImageView和一个TextView。

2、利用fragment实现交互

(1)对于两个fragment,单独去写xml文件。activity_main.xml放两个fragment组件即可,注意一定要写id和name属性(即其所对应的类名)

(2)Mainactivity.java不用写,初始化完布局即可。对于上fragment,列表需要有一个适配器(代码同上)。对于下fragment,初始化后,还要声明一个方法,供上fragment调用,以更新自己的图片和文本。


public class UpFragment extends Fragment {
    private ListView list;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
        View view=inflater.inflate(R.layout.up,container,false);
        list = view.findViewById(R.id.ls1);(数据来源同上)
        MyAdapter adapter = new MyAdapter(getContext(), data, imageIds);  
        list.setAdapter(adapter);  
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String name=data[position];
                 int img=imageIds[position];
 BottomFragment f2=(BottomFragment)getActivity().getSupportFragmentManager().findFragmentById(R.id.f2);
                f2.updateContent(name,img);   // 建一个下侧fragment对象、更新
            }
        });
        return view;
    }}

public class BottomFragment extends Fragment {

    private ImageView fruitImage;
    private TextView fruitName;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
        View view=inflater.inflate(R.layout.bottom,container,false);
        fruitImage = view.findViewById(R.id.I1);
        fruitName = view.findViewById(R.id.t1);
        return view;
    }
//    提供公开方法供 UpFragment 调用
    public void updateContent(String name, int imageResId) {
//        更新文本和图片
        fruitName.setText(name);
        fruitImage.setImageResource(imageResId);
    }
}

实验3

1、使用MediaPlayer,直接在java代码使用即可,无需在xml中声明。注意stop涉及两个方法。

2、使用VideoView。xml也要声明。java初始化后,String path = "android.resource://" + getPackageName() + "/" + R.raw.video;

videoView.setVideoURI(Uri.parse(path)); videoView.start();

终止和重放:videoView.stopPlayback(); videoView.resume();

3、单选按钮。对group设置监听器,根据id判断选的哪个。可借用布尔型变量。

实验4

1、选择不同的颜色进行绘画。需要自定义一个view作为画布(在xml文件中要声明该组件,包名.类名),还要自定义paint画笔。MainActivity只需初始化组件,想清空时,调用myView.clearCanvas(); 选择不同颜色,用到列表对话框及监听器:

String[] content = {"红色", "绿色", "蓝色", "黑色"};
int[] colorsValue = {Color.RED, Color.GREEN,Color.BLUE, Color.BLACK};
btnTest.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        new AlertDialog.Builder(MainActivity.this).setTitle("选择颜色")
                .setItems(content, ((dialog, which) -> {
                    myView.setCurrentPaintColor(colorsValue[which]);
                    textView.setText("当前颜色为:" +content[which]);
                })).show();}});

MyPaint.java
public class MyPaint {
    public Paint paint;
    public Path path;
    public MyPaint() {
        paint = new Paint();
        paint.setColor(0xFF000000); // 黑色
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);
        paint.setAntiAlias(true);
        path = new Path(); }
    public void resetPath() {
        path.reset(); }}

MyView.java

package com.example.test;
public class MyView extends View {
    private List<MyPaint> paints = new ArrayList<>();
    private MyPaint currentPaint;
    private void init() {
        currentPaint = new MyPaint();
        paints.add(currentPaint);
    }
    //    设置当前画笔颜色
    public void setCurrentPaintColor(int color) {
        currentPaint = new MyPaint(); // 新建一个 MyPaint,防止原来画的也变色了
        currentPaint.paint.setColor(color);
        paints.add(currentPaint);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (MyPaint mp : paints) {
            canvas.drawPath(mp.path, mp.paint);} }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                currentPaint.path.moveTo(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                currentPaint.path.lineTo(x, y);
                invalidate(); // 刷新界面
                break; }
        return true;}
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
     init();// 系统在从 XML 加载 View 时默认调用的构造函数
    }
      public void clearCanvas() {
        for (MyPaint mp : paints) {
            mp.resetPath();
        }  // 清屏方法
        invalidate();}}

2绘制矩形和线条

MyPaint.java
public class MyPaint {
    public Paint paint = new Paint();
    public Path path = new Path();
    public boolean isRect = false;
    public float startX, startY, endX, endY;//按下(startX/startY) 和 松开(endX/endY)
    public MyPaint() {
        paint.setAntiAlias(true);
        paint.setStrokeWidth(8);
        paint.setStyle(Paint.Style.STROKE); }
    public RectF getRectF() {//左上右下四个边界
        return new RectF(Math.min(startX, endX), Math.min(startY, endY),
                Math.max(startX, endX), Math.max(startY, endY)); }
    public void resetPath() {
        path.reset();}}

MyView.java
public class MyView extends View {有两个参数,同上初始化。
    private boolean drawRectMode = false;             // 是否为矩形绘图模式
    private int currentColor = 0xFF000000;            // 当前颜色,默认黑色
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs); }
    public void setDrawRectMode(boolean drawRect) {    // 设置是否画矩形
        this.drawRectMode = drawRect; }
    public void setCurrentPaintColor(int color) {// 设置当前颜色,仅记录颜色,不创建画笔
        this.currentColor = color;}
    public void clearCanvas() {
        paints.clear(); // 清空所有绘制内容
        invalidate(); }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (MyPaint mp : paints) {//遍历之前画的每一笔
            if (mp.isRect) {
                canvas.drawRect(mp.getRectF(), mp.paint); // 画矩形
            } else {
                canvas.drawPath(mp.path, mp.paint);       // 画线条} }}
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        if (drawRectMode) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    currentPaint = new MyPaint();
                    currentPaint.isRect = true;
                    currentPaint.paint.setColor(currentColor); // 设置颜色
                    currentPaint.startX = x;
                    currentPaint.startY = y;
                    paints.add(currentPaint);
                    break;
                case MotionEvent.ACTION_MOVE:
                case MotionEvent.ACTION_UP:
                    currentPaint.endX = x;
                    currentPaint.endY = y;
                    invalidate();
                    break;}} else {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    currentPaint = new MyPaint();
                    currentPaint.paint.setColor(currentColor); // 设置颜色
                    currentPaint.path.moveTo(x, y);
                    paints.add(currentPaint);
                    break;
                case MotionEvent.ACTION_MOVE:
                    currentPaint.path.lineTo(x, y); // 画线到当前位置
                    invalidate();
                    break;}}return true; }}

实验7 从网络获取数据并进行JSON解析

MainActivity.java
public class MainActivity extends AppCompatActivity {
    EditText mEditWeather;
    TextView mTextCityName,mTextTemp,mTextPres,mTextHumidity;
    CheckBox TempBox,PresBox,HumiBox;
    Button mButtonFresh;
    WeatherTask mCurrentTask;
    String temp="",pres="",humidity="";
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);(这里省略了组件初始化,考试要写上!
        TempBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (TempBox.isChecked())
                    mTextTemp.setText(temp+"C");
                else
                    mTextTemp.setText("");
            }
        });//PresBox,HumiBox同理,但设置文字内容不同。
        mButtonFresh.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mCurrentTask=new WeatherTask();
                mCurrentTask.execute(mEditWeather.getText().toString()); } }); }
    class WeatherTask extends AsyncTask<String,Void,DataGet.WeatherResult> {
        @Override//在后台异步获取天气信息
        protected DataGet.WeatherResult doInBackground(String... params){
            DataGet dataGet =new DataGet();
            return dataGet.getWeatherDate(params[0]); }
        @Override
        protected void onPostExecute(DataGet.WeatherResult weatherResult){
            super.onPostExecute(weatherResult);
            if(weatherResult.getErrorCode()==0){
                DecimalFormat df=new DecimalFormat("00.00");
                temp=df.format(weatherResult.getCurTemp());
                pres=weatherResult.getCurPres()+" ";
                humidity = weatherResult.getCurHumidity()+" ";
                mTextCityName.setText("城市:"+weatherResult.getCityName());}}}     
    protected void onDestroy(){
        if(mCurrentTask!=null){
            mCurrentTask.cancel(true);
            mCurrentTask=null;}
        super.onDestroy();}}

DataGet.java
public class DataGet {
    public class WeatherResult{
        private float curTemp;
        private float curPres;
        private float curHumidity;
        private int errorCode;
        private String cityName;
        public String getCityName() {return  cityName;}
        public void setCityName(String cityName) {
            this.cityName = cityName;
        }
        public int getErrorCode() {
            return errorCode;
        }
        public void setErrorCode(int errorCode) {
            this.errorCode = errorCode;
        }
        public float getCurTemp() {
            return curTemp;
        }
        public void setCurTemp(float curTemp) {
            this.curTemp = curTemp;
        }

        public float getCurPres() {
            return curPres;
        }
        public void setCurPres(float curPres) {
            this.curPres = curPres;
        }
        public float getCurHumidity() {
            return curHumidity;
        }
        public void setCurHumidity(float curHumidity) {
            this.curHumidity = curHumidity;
        }
    }
    private static final String WEATHER_URL="http://api.openweathermap.org/data/2.5/weather?";
    private static final String MyKey="6ca97ce186cc05e94b2ad45ed2a39eea";
    private float tranformToC(float abs){
        return(abs - 273.15f);
    }
    public WeatherResult getWeatherDate(String cityName){
        WeatherResult weatherResult=new WeatherResult();
        try{
            String urlString=WEATHER_URL+"q="+cityName+"&APPID="+MyKey;
            Log.i("DataGet",urlString);
            URL url=new URL(urlString);
            HttpURLConnection connection=(HttpURLConnection)url.openConnection();
            InputStream in=connection.getInputStream();
            StringBuffer stringBuffer=new StringBuffer();
            int c=0;
            while ((c=in.read())!=-1){
                stringBuffer.append((char) c);
            }
            Log.i("DataGet",stringBuffer.toString());
            WeatherParse weatherParse=new WeatherParse();
            weatherParse.setData(stringBuffer.toString());
            weatherResult.setCurTemp(tranformToC(weatherParse.getCurTemp()));
            weatherResult.setCityName(cityName);
            weatherResult.setCurPres(weatherParse.getCurPres());
            weatherResult.setCurHumidity(weatherParse.getCurHumidity());
            weatherResult.setErrorCode(0);
            return weatherResult;
        }catch (IOException e){
            e.printStackTrace();
        }     return weatherResult;}}

WeatherParse.java
public class WeatherParse {
    private float curTemp=0;
    private static final String MAIN_KEY="main";
    private static final String CUR_TEMP_KEY="temp";
    private static final String CUR_PRES_KEY="pressure";
    private float curPres=0;
    private float curHumidity=0;
    private static final String CUR_HUMIDITY_KEY="humidity";
    public void setData(String weatherInfo){
        try{
            JSONObject object=new JSONObject(weatherInfo);
            object=object.getJSONObject(MAIN_KEY);
            curTemp=(float) object.getDouble(CUR_TEMP_KEY);
            curPres=(float) object.getDouble(CUR_PRES_KEY);
            curHumidity=(float) object.getDouble(CUR_HUMIDITY_KEY);
        }catch (JSONException e){
            e.printStackTrace();
        }
    }
    public float getCurTemp() {
        return curTemp; }
    public float getCurPres() {
        return curPres; }
    public float getCurHumidity() {
        return curHumidity;}}

实验8

  1. SQLiteDataBase(第13章 数据存储)的增删改查

public class MainActivity extends AppCompatActivity {

String name;String phone;SQLiteDatabase db;ContentValues values;MyHelper myHelper;
     @Override(上下省略了组件的变量声明)
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
         myHelper=new MyHelper(this);
        mButtonAdd.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                name=mEditTextName.getText().toString();
                phone=mEditTextPhone.getText().toString();
                db=myHelper.getWritableDatabase();
                values=new ContentValues();//键值对容器 ContentValues,用于封装要插入的数据
                values.put("name",name);
                values.put("phone",phone);
                db.insert("information",null,values);//增
                db.close();}});
        mButtonQuery.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                db=myHelper.getReadableDatabase();
                Cursor cursor=db.query("information",null,null,null,null,null,null);
                if(cursor.getCount()==0){
                    mTextViewShow.setText("");
                }
                else{
                    cursor.moveToFirst();
//                    从游标中读取第2列(name)和第3列(phone)的数据。第一列是id,索引从0开始。
mTextViewShow.setText("Name : "+cursor.getString(1)+" ;Tel :"+cursor.getString(2));}
                while (cursor.moveToNext()){
mTextViewShow.append("\n"+"Name : "+cursor.getString(1)+" ;Tel : "+cursor.getString(2));}
                cursor.close();
                db.close();}});
        mButtonUpdate.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                db=myHelper.getWritableDatabase();
                values=new ContentValues();
                values.put("phone",phone=mEditTextPhone.getText().toString());
                db.update("information", values, "name=?", new String[]{mEditTextName.getText().toString()});
                db.close();}});
        mButtonDelete.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                db=myHelper.getWritableDatabase();
                db.delete("information",null,null);
                mTextViewShow.setText("");
                db.close();}});
    }
    //    创建或者打开数据库itcast,同时在数据库中创建表information
    class MyHelper extends SQLiteOpenHelper{
        public MyHelper(Context context){
            super(context,"itcast.db",null,1);}
        public void onCreate(SQLiteDatabase sqLiteDatabase){
            sqLiteDatabase.execSQL("CREATE TABLE information(_id INTEGER PRIMARY KEY AUTOINCREMENT,"+"NAME varchar(20),phone VARCHAR(20))");}
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}}}

  1. 拦截指定电话

(1)注意!Manifest.xml文件要新增权限和组件。<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-feature android:name="android.hardware.telephony" android:required="false"/>

<receiver
    android:name=".OutCallReceiver"
    android:exported="true"
    android:enabled="true">
    <intent-filter>
        <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
    </intent-filter>
</receiver>

(2)MainActivty.java
public class MainActivity extends AppCompatActivity {
    private EditText mEditTextInputNumber;
    private Button mButtonInputNumber;
    private SharedPreferences sp;
    // 手动定义权限常量(因为高版本 SDK 中已经删除)
    private static final String PERMISSION_PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        sp = getSharedPreferences("config",MODE_PRIVATE);
        mEditTextInputNumber =findViewById(R.id.edittext_input_number);
        mButtonInputNumber =findViewById(R.id.button_input_number);
        mButtonInputNumber.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Build.VERSION.SDK_INT >= 23) {//检查并动态请求"拨出电话监听权限"
if (checkSelfPermission(PERMISSION_PROCESS_OUTGOING_CALLS) != PackageManager.PERMISSION_GRANTED) {
                        requestPermissions(new String[]{PERMISSION_PROCESS_OUTGOING_CALLS}, 0);}}
                // 获取用户输入的拦截号码
                String number = mEditTextInputNumber.getText().toString().trim();
                // 保存拦截号码到 SharedPreferences
                SharedPreferences.Editor editor = sp.edit();
                editor.putString("number", number);
                editor.commit();
                Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
            } });}}

OutCallReceiver.java
public class OutCallReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 获取拨打的电话号码。getResultData() 是 BroadcastReceiver 提供的方法,用于获取当前广播处理链中传递的数据
        String outcallNumber = getResultData();
        // 创建 SharedPreferences 对象,获取拦截号码
        SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
        String number = sp.getString("number", "");
        // 判断是否是拦截电话号码
        if (outcallNumber != null && outcallNumber.equals(number)) {
            // 清除拨号操作(即取消拨打电话)
            setResultData(null);}}}


网站公告

今日签到

点亮在社区的每一天
去签到