Android Development - advanced components

Original video link

1. Use of complex components

1. Component common

1.1 display status of control components

  • xml attribute control:
  • java attribute control:
			// View is the control currently in use
			View.setVisibility(View.GONE) Control hiding
            View.setVisibility(View.VISIBLE) Control display

1.2 set touch activation status (read only)

  • java control (setEnabled)
 View.setEnabled(false);

1.3 custom styles

Custom styles: creating xml from drawable files

Just reference it in the control

2. Use of ListView (Part 1)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activitys.ListViewTest">

    <ListView
        android:id="@+id/listView_lv_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</LinearLayout>

2.1 properties

2.2 events

2.3 adapter

2.3. 1 arrayadapter (simple array adapter)

public class ListViewTest extends AppCompatActivity {

    private ListView mListViewLvTest;
    private List<String> list;
    private ArrayAdapter<String> arrayAdapter;

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

    private void setView() {
        mListViewLvTest.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Toast.makeText(getApplicationContext(),"click"+list.get(i), Toast.LENGTH_LONG).show();
            }
        });
    }

    private void initView() {
        mListViewLvTest = (ListView) findViewById(R.id.listView_lv_test);
        list = new ArrayList<>();
        list.add("Data 1");
        list.add("Data 2");
        list.add("Data 3");
        arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, list);
        mListViewLvTest.setAdapter(arrayAdapter);
    }
}

2.3. 2 baseadapter (custom adapter)

2.3. 2.1 prepare a customized View template

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:padding="10dp"
    android:layout_height="match_parent">

    <!-- there text It's not important. It's just a reminder-->
    <TextView
        android:id="@+id/adapter_listview_tv_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="15dp"
        android:text="name"/>
    
    <TextView
        android:id="@+id/adapter_listview_tv_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="15dp"
        android:text="age"/>

</LinearLayout>
2.3. 2.2 entity class for preparing data
package com.example.study1.entity;

public class ListViewEntity {

    private String name;

    private Integer age;

    public ListViewEntity() {
    }

    public ListViewEntity(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "ListViewEntity{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2.3. 2.3 preparing entity data
		listViewEntities = new ArrayList<>();
        listViewEntities.add(new ListViewEntity("Zhang San",14));
        listViewEntities.add(new ListViewEntity("Li Si",14));
        listViewEntities.add(new ListViewEntity("Wang Wu",14));
2.3. 2.4 prepare a custom BaseAdapter class
 private class ListViewAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            return listViewEntities.size();
        }

        @Override
        public Object getItem(int i) {
            return listViewEntities.get(i);
        }

        @Override
        public long getItemId(int i) {
            return i;
        }

        // Method of rendering data
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            ViewHolder vh = null;
            if(view == null){
                vh = new ViewHolder();
                // LayoutInflater. From (from which context) to obtain the layouteinflator interface layout loading class
                // java obtains the view object of a static interface by using layoutinflator Inflate (which interface layout to load)
                view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.adapter_listview_test, null);
                vh.tvName = view.findViewById(R.id.adapter_listview_tv_name);
                vh.tvAge = view.findViewById(R.id.adapter_listview_tv_age);
                // Package and store it in the current interface
                view.setTag(vh);
            }else{
                vh = (ViewHolder) view.getTag();
            }
            // Processing data
            vh.tvName.setText("name:"+ listViewEntities.get(i).getName());
            vh.tvAge.setText("Age:"+ listViewEntities.get(i).getAge());
            return view;
        }

        // Similar to DTO, it is easy to extract
        class ViewHolder{
            TextView tvName;
            TextView tvAge;
        }
    }
1.3. 2.4 setting custom adapters for the original ListView
 private void initView() {
        mListViewLvTest = (ListView) findViewById(R.id.listView_lv_test);
        listViewEntities = new ArrayList<>();
        listViewEntities.add(new ListViewEntity("Zhang San",14));
        listViewEntities.add(new ListViewEntity("Li Si",14));
        listViewEntities.add(new ListViewEntity("Wang Wu",14));
        listViewAdapter = new ListViewAdapter();
        mListViewLvTest.setAdapter(listViewAdapter);
    }

2. Use of ListView (Part 2)

2.1 plug in


==2020.3 AS cannot use the plug-in==

3. Optimize jump interface

3.1 common jump method

As long as the current interface inherits the AppCompatActivity class, there will be a startActivity() jump method

// New intent (object of the current context, jump there)
 startActivity(new Intent(getApplicationContext(), ImageViewTest.class));

3.2 optimized jump method

public void onClick(View view) {
                        // The corresponding jump effect is carried out according to the clicked element (layout bar)
                        //Intent intent = new Intent(getApplicationContext(), ImageViewTest.class);
                        //startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(
                        //        ListViewTest.this, new Pair[]{Pair.<View, String>create(holder.adapter_listview_layout, "set_Img")}
                        //).toBundle());
                        // The corresponding jump effect is performed according to the clicked element (picture)
                        Intent intent = new Intent(getApplicationContext(), ImageViewTest.class);
                        startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(
                                ListViewTest.this, new Pair[]{Pair.<View, String>create(holder.adapter_listview_iv_test, "set_Img")}
                        ).toBundle());
                    }

Bind the corresponding elements in the corresponding interface to jump to and set the jump effect

android:transitionName="set_Img"

3. Use of horizontal listhorizontallistview

3.1 understanding of simple custom View

  • Form xml style through java program
  • It can be used directly in xml
  • Export properties
  • ...
    Original address
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.Scroller;

import java.util.LinkedList;
import java.util.Queue;

public class HorizontalListView extends AdapterView<ListAdapter> {

    float startX;
    float startY;
    public boolean mAlwaysOverrideTouch = true;
    protected ListAdapter mAdapter;
    private int mLeftViewIndex = -1;
    private int mRightViewIndex = 0;
    protected int mCurrentX;
    protected int mNextX;
    private int mMaxX = Integer.MAX_VALUE;
    private int mDisplayOffset = 0;
    protected Scroller mScroller;
    private GestureDetector mGesture;
    private Queue<View> mRemovedViewQueue = new LinkedList<View>();
    private OnItemSelectedListener mOnItemSelected;
    private OnItemClickListener mOnItemClicked;
    private OnItemLongClickListener mOnItemLongClicked;
    private boolean mDataChanged = false;


    public HorizontalListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    private synchronized void initView() {
        mLeftViewIndex = -1;
        mRightViewIndex = 0;
        mDisplayOffset = 0;
        mCurrentX = 0;
        mNextX = 0;
        mMaxX = Integer.MAX_VALUE;
        mScroller = new Scroller(getContext());
        mGesture = new GestureDetector(getContext(), mOnGesture);
    }

    @Override
    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
        mOnItemSelected = listener;
    }

    @Override
    public void setOnItemClickListener(OnItemClickListener listener) {
        mOnItemClicked = listener;
    }

    @Override
    public void setOnItemLongClickListener(OnItemLongClickListener listener) {
        mOnItemLongClicked = listener;
    }

    private DataSetObserver mDataObserver = new DataSetObserver() {

        @Override
        public void onChanged() {
            synchronized (HorizontalListView.this) {
                mDataChanged = true;
            }
            invalidate();
            requestLayout();
        }

        @Override
        public void onInvalidated() {
            reset();
            invalidate();
            requestLayout();
        }
    };

    @Override
    public ListAdapter getAdapter() {
        return mAdapter;
    }

    @Override
    public View getSelectedView() {
        return null;
    }

    @Override
    public void setAdapter(ListAdapter adapter) {
        if (mAdapter != null) {
            mAdapter.unregisterDataSetObserver(mDataObserver);
        }
        mAdapter = adapter;
        mAdapter.registerDataSetObserver(mDataObserver);
        reset();
    }

    private synchronized void reset() {
        initView();
        removeAllViewsInLayout();
        requestLayout();
    }

    @Override
    public void setSelection(int position) {
    }

    private void addAndMeasureChild(final View child, int viewPos) {
        LayoutParams params = child.getLayoutParams();
        if (params == null) {
            params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        }

        addViewInLayout(child, viewPos, params, true);
        child.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
                MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
    }

    @Override
    protected synchronized void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        if (mAdapter == null) {
            return;
        }

        if (mDataChanged) {
            int oldCurrentX = mCurrentX;
            initView();
            removeAllViewsInLayout();
            mNextX = oldCurrentX;
            mDataChanged = false;
        }

        if (mScroller.computeScrollOffset()) {
            int scrollx = mScroller.getCurrX();
            mNextX = scrollx;
        }

        if (mNextX <= 0) {
            mNextX = 0;
            mScroller.forceFinished(true);
        }
        if (mNextX >= mMaxX) {
            mNextX = mMaxX;
            mScroller.forceFinished(true);
        }

        int dx = mCurrentX - mNextX;

        removeNonVisibleItems(dx);
        fillList(dx);
        positionItems(dx);

        mCurrentX = mNextX;

        if (!mScroller.isFinished()) {
            post(new Runnable() {
                @Override
                public void run() {
                    requestLayout();
                }
            });
        }
    }

    private void fillList(final int dx) {
        int edge = 0;
        View child = getChildAt(getChildCount() - 1);
        if (child != null) {
            edge = child.getRight();
        }
        fillListRight(edge, dx);

        edge = 0;
        child = getChildAt(0);
        if (child != null) {
            edge = child.getLeft();
        }
        fillListLeft(edge, dx);
    }

    private void fillListRight(int rightEdge, final int dx) {
        while (rightEdge + dx < getWidth() && mRightViewIndex < mAdapter.getCount()) {

            View child = mAdapter.getView(mRightViewIndex, mRemovedViewQueue.poll(), this);
            addAndMeasureChild(child, -1);
            rightEdge += child.getMeasuredWidth();

            if (mRightViewIndex == mAdapter.getCount() - 1) {
                mMaxX = mCurrentX + rightEdge - getWidth();
            }

            if (mMaxX < 0) {
                mMaxX = 0;
            }
            mRightViewIndex++;
        }
    }

    private void fillListLeft(int leftEdge, final int dx) {
        while (leftEdge + dx > 0 && mLeftViewIndex >= 0) {
            View child = mAdapter.getView(mLeftViewIndex, mRemovedViewQueue.poll(), this);
            addAndMeasureChild(child, 0);
            leftEdge -= child.getMeasuredWidth();
            mLeftViewIndex--;
            mDisplayOffset -= child.getMeasuredWidth();
        }
    }

    private void removeNonVisibleItems(final int dx) {
        View child = getChildAt(0);
        while (child != null && child.getRight() + dx <= 0) {
            mDisplayOffset += child.getMeasuredWidth();
            mRemovedViewQueue.offer(child);
            removeViewInLayout(child);
            mLeftViewIndex++;
            child = getChildAt(0);

        }

        child = getChildAt(getChildCount() - 1);
        while (child != null && child.getLeft() + dx >= getWidth()) {
            mRemovedViewQueue.offer(child);
            removeViewInLayout(child);
            mRightViewIndex--;
            child = getChildAt(getChildCount() - 1);
        }
    }

    private void positionItems(final int dx) {
        if (getChildCount() > 0) {
            mDisplayOffset += dx;
            int left = mDisplayOffset;
            for (int i = 0; i < getChildCount(); i++) {
                View child = getChildAt(i);
                int childWidth = child.getMeasuredWidth();
                child.layout(left, 0, left + childWidth, child.getMeasuredHeight());
                left += childWidth + child.getPaddingRight();
            }
        }
    }

    public synchronized void scrollTo(int x) {
        mScroller.startScroll(mNextX, 0, x - mNextX, 0);
        requestLayout();
    }


    /**
     * Sliding up and down requires interception,
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean handled = super.dispatchTouchEvent(ev);
        handled |= mGesture.onTouchEvent(ev);
        getParent().requestDisallowInterceptTouchEvent(true);

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = (int) ev.getX();
                startY = (int) ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                int endX = (int) ev.getX();
                int endY = (int) ev.getY();

                int dx = (int) (endX - startX);
                int dy = (int) (endY - startY);

                if (Math.abs(dx) + 50 > Math.abs(dy)) {

                } else {
                    // Sliding up and down, interception required
                    getParent().requestDisallowInterceptTouchEvent(false);
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return handled | super.dispatchTouchEvent(ev);
    }

    protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                              float velocityY) {
        synchronized (HorizontalListView.this) {
            mScroller.fling(mNextX, 0, (int) -velocityX, 0, 0, mMaxX, 0, 0);
        }
        requestLayout();
        return true;
    }

    protected boolean onDown(MotionEvent e) {
        mScroller.forceFinished(true);
        return true;
    }

    private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {

        @Override
        public boolean onDown(MotionEvent e) {
            return HorizontalListView.this.onDown(e);
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                               float velocityY) {
            return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                float distanceX, float distanceY) {

            synchronized (HorizontalListView.this) {
                mNextX += (int) distanceX;
            }
            requestLayout();
            return true;
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            for (int i = 0; i < getChildCount(); i++) {
                View child = getChildAt(i);
                if (isEventWithinView(e, child)) {
                    if (mOnItemClicked != null) {
                        mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
                    }
                    if (mOnItemSelected != null) {
                        mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
                    }
                    break;
                }
            }
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                if (isEventWithinView(e, child)) {
                    if (mOnItemLongClicked != null) {
                        mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
                    }
                    break;
                }

            }
        }

        private boolean isEventWithinView(MotionEvent e, View child) {
            Rect viewRect = new Rect();
            int[] childPosition = new int[2];
            child.getLocationOnScreen(childPosition);
            int left = childPosition[0];
            int right = left + child.getWidth();
            int top = childPosition[1];
            int bottom = top + child.getHeight();
            viewRect.set(left, top, right, bottom);
            return viewRect.contains((int) e.getRawX(), (int) e.getRawY());
        }
    };

    //Resolve slide and click conflicts
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = ev.getX();
                startY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                float endX = ev.getX();
                float endY = ev.getY();

                float dx = endX - startX;
                float dy = endY - startY;

                if (Math.abs(dx) - 10 > Math.abs(dy)) {
                    return true;
                } else if (Math.abs(dx) < Math.abs(dy) - 10) {
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }
}

Use in xml files

    <com.example.study1.customView.HorizontalListView
        android:id="@+id/horizontal_hr_test"
        android:layout_width="match_parent"
        android:layout_height="100dp">
    </com.example.study1.customView.HorizontalListView>

java settings custom adapter

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.example.study1.R;
import com.example.study1.customView.HorizontalListView;

import java.util.ArrayList;
import java.util.List;

public class HorizontalListViewTest extends AppCompatActivity {

    private HorizontalListView mHorizontalHrTest;
    private List<String> names;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_horizontal_list_view_test);
        initView();
        names = new ArrayList<>();
        names.add("Zhang San");
        names.add("Li Si");
        names.add("Wang Wu");
        names.add("Zhang San");
        names.add("Li Si");
        names.add("Wang Wu");
        names.add("Zhang San");
        names.add("Li Si");
        names.add("Wang Wu");
        names.add("Zhang San");
        names.add("Li Si");
        names.add("Wang Wu");
        AdapterHlistviewTestAdapter adapterHlistviewTestAdapter = new AdapterHlistviewTestAdapter(names, getApplicationContext());
        mHorizontalHrTest.setAdapter(adapterHlistviewTestAdapter);

    }

    private void initView() {
        mHorizontalHrTest = (HorizontalListView) findViewById(R.id.horizontal_hr_test);
    }

    public class AdapterHlistviewTestAdapter extends BaseAdapter {
        List<String> listBeans;
        Context context;

        public  AdapterHlistviewTestAdapter (List<String> listBeans, Context context){
            this.listBeans = listBeans;
            this.context = context;
        }

        @Override
        public int getCount() {
            return listBeans.size();
        }

        @Override
        public String getItem(int position) {
            return listBeans.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = LayoutInflater.from(context).inflate(R.layout.adapter_hlistview_test, null);
                convertView.setTag(new ViewHolder(convertView));
            }
            initializeViews((String)getItem(position), (ViewHolder) convertView.getTag());
            return convertView;
        }

        private void initializeViews(final String object, final ViewHolder holder) {
            //TODO implement
            try {
                //Write your logic here
                holder.adapterHlistViewTvTest.setText(object);
            }catch (Exception e){
            }
        }

        protected class ViewHolder {
            private ImageView adapterHlistViewIvTest;
            private TextView adapterHlistViewTvTest;

            public ViewHolder(View view) {
                adapterHlistViewIvTest = (ImageView) view.findViewById(R.id.adapter_hlist_view_iv_test);
                adapterHlistViewTvTest = (TextView) view.findViewById(R.id.adapter_hlist_view_tv_test);
            }
        }
    }
}

4. Use of grid list GridView

4.1 properties

4.2 associated BaseAdapter adapter

4.3 events

  • setOnItemClickListener: click event
 <!--
    numColumn: Number of columns
    verticalSpacing: Vertical space

    -->
    <GridView
        android:numColumns="3"
        android:id="@+id/grid_view_test"
        android:verticalSpacing="10dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </GridView>

Bind the corresponding adapter / set the corresponding event

public class GridViewTest extends AppCompatActivity {


    private GridView mGridViewTest;
    private List<String> names;
    private AdapterHlistviewTestAdapter listViewTestAdapter;

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

    private void setView() {
    }

    private void initView() {
        mGridViewTest = (GridView) findViewById(R.id.grid_view_test);
        names = new ArrayList<>();
        names.add("Zhang San");
        names.add("Zhang San");
        names.add("Zhang San");
        names.add("Zhang San");
        names.add("Zhang San");
        names.add("Zhang San");
        names.add("Zhang San");
        names.add("Zhang San");
        names.add("Zhang San");
        listViewTestAdapter = new AdapterHlistviewTestAdapter(names, getApplication());
        mGridViewTest.setAdapter(listViewTestAdapter);

    }

    public class AdapterHlistviewTestAdapter extends BaseAdapter {
        List<String> listBeans;
        Context context;

        public  AdapterHlistviewTestAdapter ( List<String> listBeans, Context context){
            this.listBeans = listBeans;
            this.context = context;
        }

        @Override
        public int getCount() {
            return listBeans.size();
        }

        @Override
        public String getItem(int position) {
            return listBeans.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = LayoutInflater.from(context).inflate(R.layout.adapter_hlistview_test, null);
                convertView.setTag(new ViewHolder(convertView));
            }
            initializeViews((String)getItem(position), (ViewHolder) convertView.getTag());
            return convertView;
        }

        private void initializeViews(final String object, final ViewHolder holder) {
            //TODO implement
            try {
                //Write your logic here
                holder.adapterHlistViewTvTest.setText(object);
            }catch (Exception e){
            }
        }

        protected class ViewHolder {
            private TextView adapterHlistViewTvTest;

            public ViewHolder(View view) {
                adapterHlistViewTvTest = (TextView) view.findViewById(R.id.adapter_hlist_view_tv_test);
            }
        }
    }

}

5. Use of static progress bar

5.1 SeekBar: drag bar

5.1. 1 Properties

<!--
        SeekBar 
        max: Maximum
        progress: Current value
        secondaryProgress: Cache bar
     -->
    <SeekBar
        android:id="@+id/bar_seek_test"
        android:layout_width="match_parent"
        android:max="100"
        android:progress="10"
        android:layout_height="wrap_content"
        android:secondaryProgress="20"/>

5.1. 2 events

 private SeekBar mBarSeekTest;
    private String logTag = "logStatus";

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

    private void setView() {
        // Listening events
        mBarSeekTest.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            // Progress bar change event
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                Log.d(logTag, "seekBar Changed");
            }
            // Start touching
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Log.d(logTag, "seekBar Touched");
            }
            // Stop touching
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Log.d(logTag, "seekBar Stop touching");
            }
        });
    }

    private void initView() {
        mBarSeekTest = (SeekBar) findViewById(R.id.bar_seek_test);
    }

5.2 ProgressBar: loading bar

5.2. 1 Properties

<ProgressBar
        android:id="@+id/bar_pro_test"
        android:max="100"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

5.2. 2 method

public class SeekProgressRatingBar extends AppCompatActivity implements View.OnClickListener {

    private SeekBar mBarSeekTest;
    private String logTag = "logStatus";
    private ProgressBar mBarProTest;

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

    private void setView() {
        // Listening events
        mBarSeekTest.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            // Progress bar change event
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                Log.d(logTag, "seekBar Changed");
                // View. The setvisibility (view. Gone) control is hidden
                // View.setVisibility(View.VISIBLE) control display
                if(seekBar.getProgress() == 100){
                    mBarProTest.setVisibility(View.GONE);
                }else{
                    mBarProTest.setVisibility(View.VISIBLE);
                }
            }

            // Start touching
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Log.d(logTag, "seekBar Touched");
            }

            // Stop touching
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Log.d(logTag, "seekBar Stop touching");
            }
        });
    }

    private void initView() {
        mBarSeekTest = (SeekBar) findViewById(R.id.bar_seek_test);
        mBarProTest = (ProgressBar) findViewById(R.id.bar_pro_test);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            default:
                break;
        }
    }
}

5.3 RatingBar: evaluation bar

5.2. 1 Properties

   <RatingBar
        android:numStars="5"
        android:rating="3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:secondaryProgress="20" />

5.2. 2 method

mBarRatingTest.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
            @Override
            public void onRatingChanged(RatingBar ratingBar, float v, boolean b) {
                Log.d(logTag, ""+ratingBar.getProgress());
                Toast.makeText(getApplicationContext(), "Current evaluation"+ratingBar.getProgress(), Toast.LENGTH_SHORT).show();
            }
        });

5. Use of dynamic progress bar

5.1 implementation of multiple threading methods

5.2 Handler+Thread: thread (timer / listener)

  • Create thread class
		// Dynamic thread progress bar
        Thread thread = new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        sleep(1000);
                        // Logic code

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        thread.start();

5.2. 1. The ui mechanism of the main process through the Handler

The child thread uses the Handler to modify the UI component in the main thread

  • analysis

The Message is delivered through Message, and then the Handler accepts the Message and modifies the component

  • Send message template
    Handle
 Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case MESSAGE_TEST1:
                    // The incoming message accepts the test1 message and modifies the UI of the main thread
                    mBarSeekTest.setProgress(progress);
                    mBarTvTest.setText(progress+"%");
                    break;
            }
        }
    };

Thread

			// Communicate with mainline UI through handle
             Message message = new Message();
             message.what = MESSAGE_TEST1;
             handler.sendMessage(message);

be careful
In the thread, the Message object should be re created every time it starts

6. Web pages display the use of WebView (similar to iframe)

6.1 authority

Turn on network permissions

6.2 application fields

  • app display web page
  • Simple browser
  • Front end app

6.3 method

6.3. 1 configuration

6.3. 1 use

<WebView
        android:id="@+id/web_view_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

Instance 1 (get WebView through url)

public class WebViewTest extends AppCompatActivity {

    private WebView mWebViewTest;

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

    private void initWebView(){
        // Set operable
        mWebViewTest.setWebViewClient(new WebViewClient());
        // Get browser settings
        WebSettings webSettings = mWebViewTest.getSettings();
        // Set the picture to the appropriate size
        webSettings.setUseWideViewPort(true);
    }

    private void setView() {
        mWebViewTest.loadUrl("https://www.58pic.com/?tid=1100857&utm_source=baidu&utm_medium=cpc&utm_campaign=%C9%E8%BC%C6-%BE%AB%C8%B7&utm_content=%CB%D8%B2%C4-%CD%A8%D3%C31&utm_term=%CD%BC%C6%AC&sdclkid=Asjpb5-pALoz15-N&renqun_youhua=2216851&bd_vid=7270136719499164176");
        // Initialize WebView
        initWebView();
    }

    private void initView() {
        mWebViewTest = (WebView) findViewById(R.id.web_view_test);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK){
            // If the current interface can go back
            if(mWebViewTest.canGoBack()){
                mWebViewTest.goBack();
                return false;
            }
        }
        return super.onKeyDown(keyCode, event);
    }
}

Instance 2 (get WebView through html code)

private void setView() {
//        mWebViewTest.loadUrl("https://www.58pic.com/?tid=1100857&utm_source=baidu&utm_medium=cpc&utm_campaign=%C9%E8%BC%C6-%BE%AB%C8%B7&utm_content=%CB%D8%B2%C4-%CD%A8%D3%C31&utm_term=%CD%BC%C6%AC&sdclkid=Asjpb5-pALoz15-N&renqun_youhua=2216851&bd_vid=7270136719499164176");
        String htmlData = "<h2>1111111</h2>";
        mWebViewTest.loadDataWithBaseURL("about:blank", htmlData,"text/html", "utf-8", null );
        // Initialize WebView
        initWebView();
    }

6.3. 2 monitor


Instance 3 (listening for loading completion events)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".activitys.WebViewTest">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ProgressBar
            android:id="@+id/web_view_pro_bar"
            android:layout_width="match_parent"
            android:layout_height="500dp" />
        <TextView
            android:id="@+id/web_view_tv_test"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="60dp"
            android:gravity="center"
            android:layout_centerInParent="true"
            android:text="0%">

        </TextView>
    </RelativeLayout>

    <WebView
        android:id="@+id/web_view_test"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>
public class WebViewTest extends AppCompatActivity {

    private WebView mWebViewTest;
    private ProgressBar mWebViewProBar;
    private TextView mWebViewTvTest;

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

    private void initWebView() {
        // Set operable
        mWebViewTest.setWebViewClient(new WebViewClient());
        // Get browser settings
        WebSettings webSettings = mWebViewTest.getSettings();
        // Set the picture to the appropriate size
        webSettings.setUseWideViewPort(true);
    }

    private void setView() {
        mWebViewTest.loadUrl("https://www.58pic.com/?tid=1100857&utm_source=baidu&utm_medium=cpc&utm_campaign=%C9%E8%BC%C6-%BE%AB%C8%B7&utm_content=%CB%D8%B2%C4-%CD%A8%D3%C31&utm_term=%CD%BC%C6%AC&sdclkid=Asjpb5-pALoz15-N&renqun_youhua=2216851&bd_vid=7270136719499164176");
        // Listen for loading completion events
        mWebViewTest.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                mWebViewProBar.setVisibility(View.GONE);
                mWebViewTvTest.setVisibility(View.GONE);
                mWebViewTest.setVisibility(View.VISIBLE);
            }
        });
        mWebViewTest.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                if(newProgress < 100){
                    mWebViewProBar.setProgress(newProgress);
                    mWebViewTvTest.setText(newProgress+"%");
                }else{
                    mWebViewProBar.setVisibility(View.GONE);
                    mWebViewTvTest.setVisibility(View.GONE);
                    mWebViewTest.setVisibility(View.VISIBLE);
                }
            }
        });
        // String htmlData = "<h2>1111111</h2>";
        // mWebViewTest.loadDataWithBaseURL("about:blank", htmlData,"text/html", "utf-8", null );
        // Initialize WebView
        // initWebView();
    }

    private void initView() {
        mWebViewTest = (WebView) findViewById(R.id.web_view_test);
        mWebViewProBar = (ProgressBar) findViewById(R.id.web_view_pro_bar);
        mWebViewTvTest = (TextView) findViewById(R.id.web_view_tv_test);
    }
	// Click return without exiting the program
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            // If the current interface can go back
            if (mWebViewTest.canGoBack()) {
                mWebViewTest.goBack();
                return false;
            }
        }
        return super.onKeyDown(keyCode, event);
    }
}

7. Use of Fragment interface (similar to the interface inside vue layout)

7.1 brief description

Using fragment, the screen can be divided into several pieces, then grouped for a modular management. Fragment cannot be used alone. It needs to be nested in an Activity, and its life cycle is also affected by the life cycle of the host Activity

7.2 use

7.2. 1 step 1: prepare a debris storage (space occupation)

 <LinearLayout
        android:id="@+id/fm_layout_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    </LinearLayout>

7.2. Step 2: prepare a fragment interface

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    tools:context=".fragment.Fragment01">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="I am fragment01 Interface"/>

</LinearLayout>

public class Fragment01 extends Fragment {

    private View view;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    // fragment assembly xml
        view = inflater.inflate(R.layout.activity_fragment01,container, false);
        return view;
    }
}

7.2. Step 3: replace the placeholder

  • Method 1: chain replacement < = > step by step
// Chain replacement
 getSupportFragmentManager().beginTransaction().replace(R.id.fm_layout_test, new Fragment01()).commit();    
  • Method 2: state maintenance

8. Use of the round robin component ViewPager

8.1 scope of use

  • picture viewer
  • Home page rotation picture
  • Homepage multi page (fragment)
  • ...

8.2 method

  • setCurrentItem: jump to the page (the second parameter is false: no animation)
  • Setoffsetscreenpagelimit: sets the number of cache interfaces
// The first is displayed by default
mViewPagerTest.setCurrentItem(1);

8.3 use

8.3. 1 prepare data

 private void initView() {
        mViewPagerTest = (ViewPager) findViewById(R.id.view_pager_test);
        list = new ArrayList<>();
        list.add(LayoutInflater.from(getApplication()).inflate(R.layout.activity_button_test, null));
        list.add(LayoutInflater.from(getApplication()).inflate(R.layout.activity_button_test, null));
        list.add(LayoutInflater.from(getApplication()).inflate(R.layout.activity_button_test, null));
    }

8.3. 2 set the adapter (PagerAdapter)

private void setView() {
        mViewPagerTest.setAdapter(new PagerAdapter() {

            // Gets the number of current forms
            @Override
            public int getCount() {
                return list.size();
            }

            // Determine whether it is an interface generated by an object
            @Override
            public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
                return view == object;
            }

            // Removes the current view from the ViewGroup
            @Override
            public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
                container.removeView(list.get(position));
            }

            // The object returned indicates which object the PageAdapter has loaded into the current interface, which is also the loading process of the adapter
            @NonNull
            @Override
            public Object instantiateItem(@NonNull ViewGroup container, int position) {
                mViewPagerTest.addView(list.get(position));
                return list.get(position);
            }
        });
    }

9. Use of rotation component ViewPager+Fragment+TabLayout

9.1 third party plug-in: TabLayout

Introduction to use

implementation 'com.android.support:design:27.1.1'

9.2 ViewPage+Fragment

private void setView() {
        // FragmentStatePagerAdapter has the function of caching. It does not need to initialize the view and other operations. It is processed automatically within the system
        mViewPagerTest.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
            @NonNull
            @Override
            public Fragment getItem(int position) {
                return fragments.get(position);
            }

            @Override
            public int getCount() {
                return fragments.size();
            }
        });

    }

    private void initView() {
        mViewPagerTest = (ViewPager) findViewById(R.id.view_pager_test);
        fragments = new ArrayList<>();
        fragments.add(new Fragment01());
        fragments.add(new Fragment02());
    }

9.2 TabLayout+ ViewPage +Fragment

Usage scenario

  • homepage
  • Rotation chart
  • Guide interface
  • ...

9.2. 1. Introducing TabLayout into XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".activitys.ViewPageTest">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/view_pager_tl_test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/view_pager_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

9.2.2 java control tab switching

public class ViewPageTest extends AppCompatActivity {

    private ViewPager mViewPagerTest;
    private List<Fragment> fragments;
    private List<String> titles;
    private TabLayout mViewPagerTlTest;

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

    private void setView() {

        // FragmentStatePagerAdapter has the function of caching. It does not need to initialize the view and other operations. It is automatically processed within the system - compatible with the lazy loading implemented in the previous way
        mViewPagerTest.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
            @NonNull
            @Override
            public Fragment getItem(int position) {
                return fragments.get(position);
            }

            @Override
            public int getCount() {
                return fragments.size();
            }

            @Nullable
            @Override
            public CharSequence getPageTitle(int position) {
                return titles.get(position);
            }
        });
        // Associate tabLayout with viewPager
        mViewPagerTlTest.setupWithViewPager(mViewPagerTest);
    }

    private void initView() {
        mViewPagerTest = (ViewPager) findViewById(R.id.view_pager_test);
        fragments = new ArrayList<>();
        fragments.add(new Fragment01());
        fragments.add(new Fragment02());
        mViewPagerTlTest = (TabLayout) findViewById(R.id.view_pager_tl_test);
        titles = new ArrayList<>();
        titles.add("first");
        titles.add("the second");
    }
}

10. Sideslip menu bar slidingpanelayout 𞓜 use of drawerlayout

10.1 introduction of corresponding configuration

	// SlidingPaneLayout
    implementation "androidx.slidingpanelayout:slidingpanelayout:1.1.0-beta01"

10.2 write xml interface (write dead content area)

   <androidx.slidingpanelayout.widget.SlidingPaneLayout
        android:id="@+id/sl_layout_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:background="#287777"
            android:layout_gravity="start"
            android:layout_width="240dp"
            android:layout_height="match_parent">

        </LinearLayout>
        <LinearLayout
            android:layout_gravity="right"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@mipmap/ic_launcher"/>
        </LinearLayout>

    </androidx.slidingpanelayout.widget.SlidingPaneLayout>

Through layout_gravity determines whether it is a content area or a list area
layout_gravity: start list area
layout_gravity: right content area

10.2 write xml interface (using fragment)

   <androidx.slidingpanelayout.widget.SlidingPaneLayout
        android:id="@+id/sl_layout_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:background="#287777"
            android:layout_gravity="start"
            android:layout_width="240dp"
            android:layout_height="match_parent">

        </LinearLayout>
        <LinearLayout
            android:layout_gravity="right"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </LinearLayout>

    </androidx.slidingpanelayout.widget.SlidingPaneLayout>

Through layout_gravity determines whether it is a content area or a list area
layout_gravity: start list area
layout_gravity: right content area

10.3 properties

  • attribute
    • Set transparent color
    mSlLayoutTest.setSliderFadeColor(Color.TRANSPARENT);
    
    • On / off - api
    mSlLayoutTest.openPane();
    
    • Set display style
    // Get sliding style listening
        mSlLayoutTest.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
            @Override
            public void onPanelSlide(@NonNull View panel, float slideOffset) {
                Log.d("SLDrawerLayout", slideOffset+"------");
                //Overlay style
                //panel: moved View,slideOffset: moved value
                //Overlay interface
                leftView.setScaleX(0.8f + 0.2f * slideOffset);//0.8 ~ 1 / / set X offset
                leftView.setScaleY(0.8f + 0.2f * slideOffset);//0.8 ~ 1 / / set y offset
                leftView.setAlpha(0.8f + 0.2f * slideOffset);//0.8 ~ 1 / / set transparency
                //main interface
                panel.setScaleX(1 - 0.2f * slideOffset);//1 ~ 0.8 / / set X offset
                panel.setScaleY(1 - 0.2f * slideOffset);//1 ~ 0.8 / / set y offset
                panel.setAlpha(1 - 0.8f * slideOffset);//1 ~ 0.8 / / set transparency
            }
    
            @Override
            public void onPanelOpened(@NonNull View panel) {
    
            }
    
            @Override
            public void onPanelClosed(@NonNull View panel) {
    
            }
        });
    

10.4 DrawrLayout

10. Use of drop-down refresh SwipeRefreshLayout

10.1 conditions (similar to vue's template)

There can only be one root element

10.2 use

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activitys.SwipeRefreshLayoutTest">

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:gravity="center"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Refresh"/>
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:src="@mipmap/ic_launcher"/>
        </LinearLayout>
    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>

10.3 method properties

private void setView() {
        // Set non slidable
        mSwipeRefreshTest.setEnabled(false);
        // The load animation appears
        mSwipeRefreshTest.setRefreshing(true);
        // Sets the color of the refresh box
        mSwipeRefreshTest.setColorSchemeResources(R.color.myColor2,R.color.myColor);
        new Thread(){
            @Override
            public void run() {
                try {
                    sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // Data acquisition success / failure
                mSwipeRefreshTest.setRefreshing(false);
            }
        }.start();
        // Listen for drop-down events
        mSwipeRefreshTest.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                // Pull down trigger
                // Request interface to get drop-down data
                new Thread(){
                    @Override
                    public void run() {
                        try {
                            sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // Data acquisition success / failure
                        mSwipeRefreshTest.setRefreshing(false);
                    }
                }.start();
            }
        });
    }

Keywords: Java Android xml

Added by wrongmove18 on Fri, 24 Dec 2021 10:59:15 +0200