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
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) { } });
- Set transparent color
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(); } }); }