Example explains the View class in Android and the method of customizing View control

  • 2021-07-09 09:12:27
  • OfStack

Simple Understanding and Examples of View
1. Basic concepts of View
Controls displayed in Activity are called View (the View class is the parent of all control classes such as text buttons)

2. Get the object representing View in Activity
Activity reads the layout file to generate various corresponding View objects


TextView textView=(TextView)findViewBy(R.id.textView)

3. Set the properties of view
In an xml layout file like Activity_mian. xml, what exactly is the difference between @ + id/and @ id/? Here @ can be understood as a reference, and the extra + represents your newly declared

4. Set up a listener for View
A control can bind multiple listeners that do not pass through to respond to different events:

(1) Gets the object that represents the control
(2) Defining a class to implement the listening interface implements OnClickListener
(3) Generate listening objects
(4) Bind the listener object to the control

5. Examples
Layout file (changed to vertical layout)


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  xmlns:tools="http://schemas.android.com/tools" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:orientation="vertical" 
  tools:context=".MainActivity" > 
 
  <TextView 
    android:id="@+id/textView" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textSize="80px" 
    android:background="#FF0000" 
    android:text="hello_world  Bear " /> 
   
  <Button  
    android:id="@+id/button" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:text=" Click "/> 
 
</LinearLayout> 

MianActivity file


package com.xiong.fisrt_android; 
 
import android.app.Activity; 
import android.graphics.Color; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.TextView; 
 
public class MainActivity extends Activity { 
 
  private TextView textView; 
  private Button button; 
  private int count = 0; 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    textView = (TextView) findViewById(R.id.textView); 
    button = (Button) findViewById(R.id.button); 
    textView.setText("hello Android!!!"); 
    textView.setBackgroundColor(Color.BLUE); 
    ButtoneListener buttoneListener = new ButtoneListener();//  Generate listening objects  
    button.setOnClickListener(buttoneListener);//  Button binding 1 Monitor  
  } 
 
  @Override 
  public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
  } 
 
  class ButtoneListener implements OnClickListener//  Create 1 Classes implement the interface for listening for events  
  { 
 
    @Override 
    public void onClick(View arg0) { 
      // TODO Auto-generated method stub 
      count++; 
      textView.setText(Integer.toString(count)); 
 
    } 
 
  } 
 
} 

Customization of View
By inheriting View, you can easily customize personalized controls.

The most important thing to realize custom View is to rewrite onDraw (Canvas canvas) function. When the system redraws the interface every time, it will call this function and pass down an Canvas. In this function, the contents to be displayed by this View should be draw to this Canvas, and the contents displayed by the interface are almost determined by this Canvas. The specific drawing method of Canvas can be easily found. It should be said that the naming of all functions in Android is very intuitive and clear. If you look at the function name under 1, you can probably understand what this function is useful for. SDK is also the best tool for querying Android API. It is definitely beneficial to use more.

The main decider of the displayed size of View is Parent Layout. View can customize its own minimum value of width and height, but this does not guarantee that it can reach this minimum value, if the size of Parent itself is already smaller than this value.

Redrawing of View-The system will not often call OnDraw function of View. In order to realize animation effect on View, such as games (but it seems that many games are realized with more efficient SurfaceView), after the main thread is the logic of executing the program, it should call postInvalidate () and inform the system to call onDraw function to redraw the interface, so as to show the animation effect.

The following code is a simulation of two ball collision View written by myself, mainly by a thread to constantly update the position of two balls in View, found that two balls and wall collision, change the logical parameters of the ball, after the update, call postInvalidate (), redraw the interface. To achieve the effect


package com.androidclub.elfman.homework3; 
import java.util.ArrayList; 
import java.util.Random; 
import android.app.Activity; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Paint.Style; 
import android.os.Bundle; 
import android.view.View; 
public class Main extends Activity { 
  TheScreen mScreen; 
  @Override 
  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    //mScreen Is custom View 
    mScreen = new TheScreen(this); 
    setContentView(mScreen); 
  } 
   
  // To avoid the thread still running after the program exits , Causing unnecessary waste of system resources , In Activity It's time to quit , Actively stop the thread  
  @Override 
  public void onDestroy() 
  { 
    mScreen.stopDrawing(); 
    super.onDestroy(); 
  } 
} 
/** 
 *  Custom View Class , Simulation of collision between two balls  
 * @author windy 
 * 
 */ 
class TheScreen extends View 
{ 
   
  private static final String TAG = "Draw"; 
  // Control variables of interface main thread  
  private boolean drawing = false; 
  // Store the information of the currently existing ball  
  private ArrayList<Circle> circles; 
  private Paint mPaint; 
  // The range of motion of two balls  
  public static final int WIDTH = 300; 
  public static final int HEIGHT = 400; 
  public static final double PI = 3.14159265; 
  Paint mPaint2 = new Paint(); 
  public TheScreen(Context context) 
  { 
    super(context); 
    circles = new ArrayList<Circle>(); 
    // Joined two balls  
    circles.add(new Circle()); 
    circles.add(new Circle(20, 30, 10)); 
    mPaint = new Paint(); 
    mPaint.setColor(Color.YELLOW); 
    mPaint.setAntiAlias(true); 
    mPaint2.setStyle(Style.STROKE); 
    mPaint2.setColor(Color.RED); 
    mPaint2.setAntiAlias(true); 
    // Start interface thread , Start automatic update interface  
    drawing = true; 
    new Thread(mRunnable).start(); 
  } 
   
  private Runnable mRunnable = new Runnable() { 
    // Main thread of interface  
    @Override 
    public void run() { 
      while( drawing ) 
      { 
        try { 
          // Update the position information of the ball  
          update(); 
          // Notify the system update interface , Equivalent to calling the onDraw Function  
          postInvalidate(); 
          // Frequency of interface updates , Here is every 30ms Update 1 Sub-interface  
          Thread.sleep(30); 
          //Log.e(TAG, "drawing"); 
        } catch (InterruptedException e) { 
          e.printStackTrace(); 
        } 
      } 
    } 
  }; 
   
  public void stopDrawing() 
  { 
    drawing = false; 
  } 
   
   
  @Override 
  public void onDraw(Canvas canvas) 
  { 
    // In canvas Draw top border  
    canvas.drawRect(0, 0, WIDTH, HEIGHT, mPaint2); 
    // In canvas Draw the ball on top  
    for( Circle circle : circles) 
    { 
      canvas.drawCircle(circle.x, circle.y, circle.radius, mPaint); 
    } 
  } 
   
  // Logic function of interface , Mainly check whether the ball collides , And update the position of the ball  
  private void update() 
  { 
    if( circles.size()>1) 
    { 
      for( int i1=0; i1<circles.size()-1; i1++) 
      { 
        // When two balls collide, , Exchange the angle values of two balls  
        for( int i2=i1+1; i2<circles.size(); i2++) 
          if( checkBumb(circles.get(i1),circles.get(i2))) 
          { 
            circles.get(i1).changeDerection(circles.get(i2)); 
          } 
      } 
       
    } 
    // Update the position of the ball  
    for( Circle circle: circles) 
      circle.updateLocate(); 
  } 
   
  private boolean checkBumb(Circle c1, Circle c2) 
  { 
    return (c1.x-c2.x)*(c1.x-c2.x) + (c1.y-c2.y)*(c1.y-c2.y) <= (c1.radius+c2.radius)*(c1.radius+c2.radius);      
  } 
   
  /** 
   *  Custom View Inner class of , Store every 1 Information of a ball  
   * @author windy 
   * 
   */ 
  class Circle 
  { 
    float x=50; 
    float y=70; 
    double angle= (new Random().nextFloat())*2*PI;; 
    int speed=4; 
    int radius=10; 
     
    public Circle() { 
    } 
     
    public Circle( float x, float y, int r ) 
    { 
      this.x = x; 
      this.y = y; 
      radius = r; 
    } 
     
    // Utilization 3 The angle function calculates the new position value of the ball , When colliding with the boundary, , Change the angle of the ball  
    public void updateLocate() 
    { 
      x = x+ (float)(speed *Math.cos(angle)); 
      //Log.v(TAG, Math.cos(angle)+""); 
      y = y+ (float)(speed *Math.sin(angle)); 
      //Log.v(TAG, Math.cos(angle)+""); 
      if( (x+radius)>=WIDTH ) 
      { 
        if( angle >=0 && angle <= (PI/2)) 
          angle = PI - angle; 
        if( angle > 1.5 * PI && angle <= 2*PI) 
          angle = 3 * PI - angle;        
      } 
      if( x-radius <=0 ) 
      { 
        if( angle >= PI && angle <= 1.5*PI ) 
          angle = 3*PI - angle; 
        if( angle >= PI/2 && angle < PI) 
          angle = PI - angle; 
      } 
      if( y-radius<=0 || y+radius>=HEIGHT) 
        angle = 2*PI - angle; 
       
    } 
    // Two-ball exchange angle  
    public void changeDerection(Circle other) 
    { 
      double temp = this.angle; 
      this.angle = other.angle; 
      other.angle = temp; 
    } 
  } 
} 

This code has been written with comments, which will be introduced next time. . . It should not be difficult to understand it.


Related articles: