Android基础知识——开发中遇到的问题

1.动态控制布局的位置

在开发时,我们可能需要在同一活动中的不同界面下来改变布局的位置使得布局处于一个比较合理的位置。

例如:我们在活动的主界面希望用户能有沉浸式的体验,所以我们将我们的布局延伸到了系统栏中,可是当我们转换到设置(碎片)的界面时,就很有可能发生系统栏中的图标,将我们界面上标题栏的部分按钮遮挡的情况。而为了解决这一问题我们就要在代码中对布局位置进行控制了。

代码展示:

FrameLayout.LayoutParams layoutParams;
layoutParams=(FrameLayout.LayoutParams) view.findViewById(R.id.choose_layout).getLayoutParams();
if(getActivity() instanceof WeatherActivity){
    
    
    //动态控制布局的margin属性
    layoutParams.topMargin=50;
}

2.单选按钮的使用

在开发时,很多时候都会让用户选择让某一项功能开启还是关闭,这个时候就需要一个比较美观的控件来实现这一功能了。

效果展示:

代码展示:

//声明依赖
dependencies {
    
    
    implementation 'com.github.zcweng:switch-button:0.0.3'
}
//布局文件中用法
<com.suke.widget.SwitchButton
    android:id="@+id/switch_button"
    android:layout_gravity="center"
    android:layout_marginLeft="60dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
//逻辑文件中用法
switchButton.setChecked();//设置控件的开关状态
switchButton.setOnCheckedChangeListener(new SwitchButton.OnCheckedChangeListener() {
    
    
    @Override
    public void onCheckedChanged(SwitchButton view, boolean isChecked) {
    
    //点击事件
        if(isChecked==true){
    
    
            //当控件变为true时的逻辑代码
        }else if(isChecked==false){
    
    
            //当控件变为false时的逻辑代码
        }
    }
});

3.仅在需要时才显示布局

在开发时,我们可能会需要先隐藏部分布局,然后当用户执行某一操作后再将这部分布局显现出来。为了实现这一功能我给大家介绍两种方法,并为大家指出它们的利弊。

3.1控制布局的可见属性

我们需要先将需隐藏布局的可见属性设置为View.GONE,然后在用户执行某一操作后将可见属性设置为View.VISIBLE即可轻易实现这一功能。

3.2ViewStub

我们也可以使用ViewStub控件来帮助我们实现这一功能。

代码展示:

//待隐藏布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
 
    <EditText
        android:id="@+id/edit_extra1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:hint="Extra field 1" />
 
    <EditText
        android:id="@+id/edit_extra2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="10dp"
        android:hint="Extra field 2" />
 
    <EditText
        android:id="@+id/edit_extra3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="10dp"
        android:hint="Extra field 3" />
 
</LinearLayout>
//主界面布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
 
    <EditText
        android:id="@+id/edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="10dp"
        android:hint="@string/edit_something_here" />
 
    <Button
        android:id="@+id/more"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_marginRight="20dp"
        android:layout_marginBottom="10dp"
        android:text="More" />
    
    <ViewStub 
        android:id="@+id/view_stub"
        android:layout="@layout/profile_extra"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
 
</LinearLayout>
//逻辑代码
private EditText editExtra1;
private EditText editExtra2;
private EditText editExtra3;

public void onMoreClick() {
    
    //当我们点击more按钮时执行该函数,即可是实现隐藏布局的显示
	ViewStub viewStub = (ViewStub) findViewById(R.id.view_stub);
	if (viewStub != null) {
    
    
		View inflatedView = viewStub.inflate();
		editExtra1 = (EditText) inflatedView.findViewById(R.id.edit_extra1);
		editExtra2 = (EditText) inflatedView.findViewById(R.id.edit_extra2);
		editExtra3 = (EditText) inflatedView.findViewById(R.id.edit_extra3);
	}

3.3以上两种方法的利弊

第一种方法:

  • 优点:逻辑简单而且控制起来比较灵活。

  • 缺点:耗费资源。虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。也就是说,会耗费内存等资源。

第二种方法:

  • 优点:在Inflate布局的时候,只有ViewStub会被初始化,然后当ViewStub被设置为可见的时候,或是调用了ViewStub.inflate()的时候,ViewStub所向的布局就会被Inflate和实例化,然后ViewStub的布局属性都会传给它所指向的布局。这样,就可以使用ViewStub来方便的在运行时,要还是不要显示某个布局。这样也就节省了内存资源,实现了布局的优化。

  • 特点:ViewStub只能Inflate一次,之后ViewStub对象会被置为空。也就是说,某个被ViewStub指定的布局被Inflate后,就不能再通过ViewStub来控制它了;ViewStub只能用来Inflate一个布局文件,而不是某个具体的View,当然也可以把View写在某个布局文件中。

  • 缺点:在程序的运行期间,某个布局在Inflate后,就不会有变化,除非重新启动。也就是说,不能再将加载出来的布局隐藏了;只能控制显示与隐藏的是布局文件,而非某个View。

4.判断ImageView展示的是哪一张图片

在开发时,我们有可能要根据ImageView展示的图片,来决定让其执行哪一点击事件。而要实现这一功能就需要判断先ImageView展示的是哪一张图片。

代码展示:

moreImage.setOnClickListener(new View.OnClickListener() {
    
    
    @Override
    public void onClick(View view) {
    
    
        if(moreImage.getDrawable().getCurrent().getConstantState().equals(ContextCompat.getDrawable(SettingActivity.this,R.drawable.many).getConstantState())){
    
    //判断方法
            //具体逻辑
        }else {
    
    
            //具体逻辑
        }
    }
});

5.单选框的使用

在开发时,我们有时需要提供一组选项,来让用户选择一个。而实现这一功能就要利用单选框控件了。

代码展示:

//布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <RadioGroup
        android:id="@+id/radio_group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <RadioButton
            android:id="@+id/eight_time"
            android:layout_margin="10dp"
            android:text="8小时"
            android:textSize="20sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <RadioButton
            android:id="@+id/four_time"
            android:layout_margin="10dp"
            android:text="4小时"
            android:textSize="20sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <RadioButton
            android:id="@+id/two_time"
            android:layout_margin="10dp"
            android:text="2小时"
            android:textSize="20sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <RadioButton
            android:id="@+id/one_time"
            android:layout_margin="10dp"
            android:text="1小时"
            android:textSize="20sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </RadioGroup>

</LinearLayout>
//逻辑代码
radioGroup.check();//设置哪一单选框为选中状态
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
    
    //点击事件
    @Override
    public void onCheckedChanged(RadioGroup radioGroup, int i) {
    
    
        switch (i){
    
    
            case R.id.eight_time:
                //选中后的逻辑代码
                break;
            case R.id.four_time:
                //选中后的逻辑代码
                break;
            case R.id.two_time:
                 //选中后的逻辑代码
                break;
            case R.id.one_time:
                 //选中后的逻辑代码
                break;
            default:
        }
    }
}

6.RecyclerView实现侧滑删除

在开发中,我们有时需要实现侧滑RecyclerView的某一子项布局来删除它的功能。

以下代码中省略了RecyclerView的基本实现方法,倘若有读者还不太清楚,请移步这里

代码展示:

//为RecycleView绑定触摸事件
ItemTouchHelper helper=new ItemTouchHelper(new ItemTouchHelper.Callback() {
    
    

    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
    
    
    	//首先回调的方法 返回int表示是否监听该方向
        int dragFlags = ItemTouchHelper.UP|ItemTouchHelper.DOWN;//拖拽
        int swipeFlags = ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;//侧滑删除
        return makeMovementFlags(dragFlags,swipeFlags);
    }
    
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
    
    
    	//滑动事件
        return false;
    }
    
    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
    
    
    	//侧滑事件
        nameList.remove(viewHolder.getAdapterPosition());
        myAdapter.notifyItemRemoved(viewHolder.getAdapterPosition());
    }
    
});
helper.attachToRecyclerView(recyclerView);

注意:倘若你还需在侧滑事件中删除数据库的内容,要将其放在remove函数之前,否则getAdapterPosition()的返回值会发生变化。

7.在活动中处理RecyclerView的点击事件

当我们在处理RecyclerView的点击事件时很有可能还要用到活动中的一些数据,而一般情况下RecyclerView的点击事件是在其适配器中注册的,这就使得你可能无法在点击事件中实现某些功能了。而为了解决在活动中处理点击事件这一问题,我们可以利用回调接口来实现。

代码展示:

//定义接口
public interface OnItemClickListener {
    
    
    void onItemClick(int position);
}
//在适配器的点击事件中调用该接口中的方法
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    
    

    private List<Saved> list=new ArrayList<>();
    private OnItemClickListener Listener=null;
    
    public MyAdapter(List<Saved> list, OnItemClickListener Listener){
    
    //我们还需要在构造方法传入该接口
        this.Listener=Listener;
        this.list=list;
    }
    
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, final int viewType) {
    
    
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item,parent,false);
        final ViewHolder viewHolder=new ViewHolder(view);
        view.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View view) {
    
    
                Listener.onItemClick(viewHolder.getAdapterPosition());//调用接口中的方法
            }
        });
        return viewHolder;
    }

	......
}
//在活动中实现该接口中的方法
OnItemClickListener recyclerListener=new OnItemClickListener() {
    
    
    @Override
    public void onItemClick(int position) {
    
    
        //具体逻辑代码
    }
};

猜你喜欢

转载自blog.csdn.net/ABded/article/details/109148100