fbpixel
Etiquetas: ,

Una vez que su primera aplicación React Native ha sido creada y está en funcionamiento, es posible que desee reutilizar ciertos elementos como componentes funcionales. Estos componentes pueden configurarse para otras aplicaciones y compartirse como una biblioteca.

Descripción

En este tutorial, vamos a empezar con una aplicación sencilla que contiene cuatro botones. Vamos a crear un componente funcional configurable de React Native en un archivo fuente que reutilizaremos en el archivo principal de la aplicación.

Veremos cómo:

  • pasar propiedades a un componente
  • recuperar datos de componentes a partir de eventos
  • utilizar un componente definido en un archivo fuente en el archivo principal

Aplicación básica: 4 botones

En este código, tenemos una vista principal (View) que cubre la pantalla, el título de la aplicación, y la vista que contiene los 4 botones. Las funciones que se realizan al pulsar los botones y los estilos definidos.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/**
* https://github.com/jim-at-jibba/react-native-game-pad
* https://github.com/ionkorol/react-native-joystick
*
*/
import React from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
const GamePad = () => {
let btnAColor = "red",
btnBColor = "orange",
btnXColor = "royalblue",
btnYColor = "limegreen"
const onButtonAPress = () => {
console.log('You clicked button A');
};
const onButtonBPress = () => {
console.log('You clicked button B');
};
const onButtonXPress = () => {
console.log('You clicked button X');
};
const onButtonYPress = () => {
console.log('You clicked button Y');
};
return (
<View style={styles.mainBody}>
<Text
style={styles.mainTitle}>
AC Controller
</Text>
<View style={{ flex: 1,justifyContent: "center", alignItems: "center",}}>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"green",
zIndex: 100,
}}
>
<TouchableOpacity
style={[styles.button, { top:"30%",backgroundColor: `${btnXColor}` }]} //top:"30%", right:"1%",
onPress={() => onButtonXPress()}
>
<Text style={styles.buttonText}>X</Text>
</TouchableOpacity>
</View>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"gold",
}}
>
<TouchableOpacity
style={[styles.button, { top: "50%", right:"20%", backgroundColor: `${btnYColor}` }]} //top:"2%", left:"10%",
onPress={() => onButtonYPress()}
>
<Text style={styles.buttonText}>Y</Text>
</TouchableOpacity>
</View>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"blue",
}}
>
<TouchableOpacity
style={[styles.button, { bottom:"50%", left:"20%", backgroundColor: `${btnAColor}` }]} //bottom:"2%",
onPress={() => onButtonAPress()}
>
<Text style={styles.buttonText}>A</Text>
</TouchableOpacity>
</View>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"red",
}}
>
<TouchableOpacity
style={[styles.button, { bottom:"30%", backgroundColor: `${btnBColor}` }]} //bottom:"30%", left:"1%",
onPress={() => onButtonBPress()}
>
<Text style={styles.buttonText}>B</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
}
export default GamePad;
//parameters
let BACKGROUND_COLOR = "#161616"; //191A19
let BUTTON_COLOR = "#346751"; //1E5128
let ERROR_COLOR = "#C84B31"; //4E9F3D
let TEXT_COLOR = "#ECDBBA"; //D8E9A8
const styles = StyleSheet.create({
mainBody: {
flex:1,
justifyContent: 'center',
alignItems: "center",
color:TEXT_COLOR,
backgroundColor: BACKGROUND_COLOR,
},
mainTitle:{
color: TEXT_COLOR,
fontSize: 30,
textAlign: 'center',
borderBottomWidth: 2,
borderBottomColor: ERROR_COLOR,
width:"100%"
},
button: {
height: 90,
width: 90,
borderRadius: 90 / 2,
justifyContent: "center",
alignItems: "center"
},
buttonText: {
fontSize: 22,
color: "white",
fontWeight: "700"
},
});
/** * https://github.com/jim-at-jibba/react-native-game-pad * https://github.com/ionkorol/react-native-joystick * */ import React from "react"; import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; const GamePad = () => { let btnAColor = "red", btnBColor = "orange", btnXColor = "royalblue", btnYColor = "limegreen" const onButtonAPress = () => { console.log('You clicked button A'); }; const onButtonBPress = () => { console.log('You clicked button B'); }; const onButtonXPress = () => { console.log('You clicked button X'); }; const onButtonYPress = () => { console.log('You clicked button Y'); }; return ( <View style={styles.mainBody}> <Text style={styles.mainTitle}> AC Controller </Text> <View style={{ flex: 1,justifyContent: "center", alignItems: "center",}}> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"green", zIndex: 100, }} > <TouchableOpacity style={[styles.button, { top:"30%",backgroundColor: `${btnXColor}` }]} //top:"30%", right:"1%", onPress={() => onButtonXPress()} > <Text style={styles.buttonText}>X</Text> </TouchableOpacity> </View> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"gold", }} > <TouchableOpacity style={[styles.button, { top: "50%", right:"20%", backgroundColor: `${btnYColor}` }]} //top:"2%", left:"10%", onPress={() => onButtonYPress()} > <Text style={styles.buttonText}>Y</Text> </TouchableOpacity> </View> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"blue", }} > <TouchableOpacity style={[styles.button, { bottom:"50%", left:"20%", backgroundColor: `${btnAColor}` }]} //bottom:"2%", onPress={() => onButtonAPress()} > <Text style={styles.buttonText}>A</Text> </TouchableOpacity> </View> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"red", }} > <TouchableOpacity style={[styles.button, { bottom:"30%", backgroundColor: `${btnBColor}` }]} //bottom:"30%", left:"1%", onPress={() => onButtonBPress()} > <Text style={styles.buttonText}>B</Text> </TouchableOpacity> </View> </View> </View> ); } export default GamePad; //parameters let BACKGROUND_COLOR = "#161616"; //191A19 let BUTTON_COLOR = "#346751"; //1E5128 let ERROR_COLOR = "#C84B31"; //4E9F3D let TEXT_COLOR = "#ECDBBA"; //D8E9A8 const styles = StyleSheet.create({ mainBody: { flex:1, justifyContent: 'center', alignItems: "center", color:TEXT_COLOR, backgroundColor: BACKGROUND_COLOR, }, mainTitle:{ color: TEXT_COLOR, fontSize: 30, textAlign: 'center', borderBottomWidth: 2, borderBottomColor: ERROR_COLOR, width:"100%" }, button: { height: 90, width: 90, borderRadius: 90 / 2, justifyContent: "center", alignItems: "center" }, buttonText: { fontSize: 22, color: "white", fontWeight: "700" }, });
/**
 * https://github.com/jim-at-jibba/react-native-game-pad
 * https://github.com/ionkorol/react-native-joystick
 * 
 */
import React from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";


const GamePad = () =>  {

  let btnAColor = "red",
      btnBColor = "orange",
      btnXColor = "royalblue",
      btnYColor = "limegreen"

  const onButtonAPress = () => {
    console.log('You clicked button A');
  };
  const onButtonBPress = () => {
    console.log('You clicked button B');
  };

  const onButtonXPress = () => {
    console.log('You clicked button X');
  };
  const onButtonYPress = () => {
    console.log('You clicked button Y');
  };

 
    return (
      <View style={styles.mainBody}>
          <Text
            style={styles.mainTitle}>
            AC Controller
          </Text>
          <View style={{ flex: 1,justifyContent: "center", alignItems: "center",}}>
              <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"green",
                  zIndex: 100,
                }}
              >
                <TouchableOpacity
                  style={[styles.button, {  top:"30%",backgroundColor: `${btnXColor}` }]} //top:"30%", right:"1%", 
                  onPress={() => onButtonXPress()}
                >
                  <Text style={styles.buttonText}>X</Text>
                </TouchableOpacity>
              </View>

              <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"gold",
                }}
              >
                <TouchableOpacity
                  style={[styles.button, { top: "50%", right:"20%", backgroundColor: `${btnYColor}` }]} //top:"2%", left:"10%",
                  onPress={() => onButtonYPress()}
                >
                  <Text style={styles.buttonText}>Y</Text>
                </TouchableOpacity>
              </View>

              <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"blue",
                }}
              >
                <TouchableOpacity
                  style={[styles.button, { bottom:"50%", left:"20%", backgroundColor: `${btnAColor}` }]} //bottom:"2%", 
                  onPress={() => onButtonAPress()}
                >
                  <Text style={styles.buttonText}>A</Text>
                </TouchableOpacity>
              </View>


            <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"red",
                }}
              >
                <TouchableOpacity
                  style={[styles.button, { bottom:"30%", backgroundColor: `${btnBColor}` }]} //bottom:"30%", left:"1%",
                  onPress={() => onButtonBPress()}
                >
                  <Text style={styles.buttonText}>B</Text>
                </TouchableOpacity>
              </View>

          </View>
      </View>            

    );
}
export default GamePad;

//parameters
let BACKGROUND_COLOR = "#161616"; //191A19
let BUTTON_COLOR = "#346751"; //1E5128
let ERROR_COLOR = "#C84B31"; //4E9F3D
let TEXT_COLOR = "#ECDBBA"; //D8E9A8

const styles = StyleSheet.create({

  mainBody: {
    flex:1,
    justifyContent: 'center',
    alignItems: "center",
    color:TEXT_COLOR,
    backgroundColor: BACKGROUND_COLOR,
  },

  mainTitle:{
    color: TEXT_COLOR,
    fontSize: 30,
    textAlign: 'center',
    borderBottomWidth: 2,
    borderBottomColor: ERROR_COLOR,
    width:"100%"
  },

  button: {
    height: 90,
    width: 90,
    borderRadius: 90 / 2,
    justifyContent: "center",
    alignItems: "center"
  },
  buttonText: {
    fontSize: 22,
    color: "white",
    fontWeight: "700"
  },


});

al pulsar los botones se ejecutan correctamente las funciones del evento

react-native-4buttons Creación de un componente funcional con React Native
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
BUNDLE ./index.js
LOG Running "CustomApp" with {"rootTag":31}
LOG You clicked button Y
LOG You clicked button X
LOG You clicked button A
LOG You clicked button B
BUNDLE ./index.js LOG Running "CustomApp" with {"rootTag":31} LOG You clicked button Y LOG You clicked button X LOG You clicked button A LOG You clicked button B
 BUNDLE  ./index.js

 LOG  Running "CustomApp" with {"rootTag":31}
 LOG  You clicked button Y
 LOG  You clicked button X
 LOG  You clicked button A
 LOG  You clicked button B

Llamar al componente desde un archivo fuente

Vamos a colocar este código en un archivo .

Para poder utilizarla, utilizamos la palabra clave export para definir la función

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
export const ButtonPad = () => {
...
}
export const ButtonPad = () => { ... }
export const ButtonPad = ()  =>  {
...
}

A continuación, el componente puede utilizarse importándolo

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import {ButtonPad} from "./src/ACJoysticks";
const GamePad = () => {
return (
<View style={styles.mainBody}>
<Text
style={styles.mainTitle}>
AC Controller
</Text>
<ButtonPad/>
</View>
);
};
export default GamePad;
import {ButtonPad} from "./src/ACJoysticks"; const GamePad = () => { return ( <View style={styles.mainBody}> <Text style={styles.mainTitle}> AC Controller </Text> <ButtonPad/> </View> ); }; export default GamePad;
import {ButtonPad} from "./src/ACJoysticks";
const GamePad = () =>  {
    return (
      <View style={styles.mainBody}>
          <Text
            style={styles.mainTitle}>
            AC Controller
          </Text>
          <ButtonPad/>
      </View>            

    );
};
export default GamePad;

Pasar propiedades a un componente funcional

Para que el componente sea configurable, definimos parámetros en el fichero principal que se pasarán a las propiedades del componente. Las propiedades que queremos pasar al componente son:

  • el texto que aparece en los botones
  • el color de los botones
  • el tamaño de los botones
  • la función onClick, que gestiona todos los botones

Los parámetros del componente se colocan en un ButtonPadProps tipo

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
type ButtonPadProps = {
radius?: number;
names?: string[4];
colors?: string[4];
onClick?:(evt: ButtonPadEvent) => void;
};
type ButtonPadProps = { radius?: number; names?: string[4]; colors?: string[4]; onClick?:(evt: ButtonPadEvent) => void; };
type ButtonPadProps = {
  radius?: number;
  names?: string[4];
  colors?: string[4];
  onClick?:(evt: ButtonPadEvent) => void;
};

A continuación, podemos definir estas propiedades como entrada del componente y llamarlas con valores por defecto.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
export const ButtonPad = (props : ButtonPadProps) => {
const { onClick, radius = 45, names= ['X','Y','A','B'], colors = ["royalblue","limegreen","red","orange"] } = props;
export const ButtonPad = (props : ButtonPadProps) => { const { onClick, radius = 45, names= ['X','Y','A','B'], colors = ["royalblue","limegreen","red","orange"] } = props;
export const ButtonPad = (props : ButtonPadProps)  =>  {
  const { onClick, radius = 45, names= ['X','Y','A','B'], colors = ["royalblue","limegreen","red","orange"] } = props;

Definimos una única función para llamar a los botones

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const onButtonPress = (index:number) => {
console.log('You clicked button ' + names[index]);
};
const onButtonPress = (index:number) => { console.log('You clicked button ' + names[index]); };
  const onButtonPress = (index:number) => {
    console.log('You clicked button ' + names[index]);
  };

Por último, modificamos el código para tener en cuenta las distintas propiedades.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/**
* ButtonPad
*/
type ButtonPadProps = {
radius?: number;
names?: Array<string>;
colors?: Array<string>;
onClick?:(evt: ButtonPadEvent) => void;
};
export const ButtonPad = (props : ButtonPadProps) => {
const { onClick, radius = 45, names= ['X','Y','A','B'], colors = ["royalblue","limegreen","red","orange"] } = props;
let textSize = radius;
const onButtonPress = (index:number) => {
console.log('You clicked button ' + names[index]);
};
return (
<View style={{ flex: 1,justifyContent: "center", alignItems: "center",}}>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"green",
zIndex: 100,
}}
>
<TouchableOpacity
style={[{
height: 2*radius,
width: 2*radius,
borderRadius: radius,
justifyContent: "center",
alignItems: "center"
}, { top:"30%",backgroundColor: `${colors[0]}` }]} //top:"30%", right:"1%",
onPress={() => onButtonPress(0)}
>
<Text style={{
fontSize: textSize,
color: "white",
fontWeight: "700"
}}>{names[0]}</Text>
</TouchableOpacity>
</View>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"gold",
}}
>
<TouchableOpacity
style={[{
height: 2*radius,
width: 2*radius,
borderRadius: radius,
justifyContent: "center",
alignItems: "center"
}, { top: "50%", right:"20%", backgroundColor: `${colors[1]}` }]} //top:"2%", left:"10%",
onPress={() => onButtonPress(1)}
>
<Text style={{
fontSize: textSize,
color: "white",
fontWeight: "700"
}}>{names[1]}</Text>
</TouchableOpacity>
</View>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"blue",
}}
>
<TouchableOpacity
style={[{
height: 2*radius,
width: 2*radius,
borderRadius: radius,
justifyContent: "center",
alignItems: "center"
}, { bottom:"50%", left:"20%", backgroundColor: `${colors[2]}` }]} //bottom:"2%",
onPress={() => onButtonPress(2)}
>
<Text style={{
fontSize: textSize,
color: "white",
fontWeight: "700"
}}>{names[2]}</Text>
</TouchableOpacity>
</View>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"red",
}}
>
<TouchableOpacity
style={[{
height: 2*radius,
width: 2*radius,
borderRadius: radius,
justifyContent: "center",
alignItems: "center"
}, { bottom:"30%", backgroundColor: `${colors[3]}` }]} //bottom:"30%", left:"1%",
onPress={() => onButtonPress(3)}
>
<Text style={{
fontSize: textSize,
color: "white",
fontWeight: "700"
}}>{names[3]}</Text>
</TouchableOpacity>
</View>
</View>
);
}
/** * ButtonPad */ type ButtonPadProps = { radius?: number; names?: Array<string>; colors?: Array<string>; onClick?:(evt: ButtonPadEvent) => void; }; export const ButtonPad = (props : ButtonPadProps) => { const { onClick, radius = 45, names= ['X','Y','A','B'], colors = ["royalblue","limegreen","red","orange"] } = props; let textSize = radius; const onButtonPress = (index:number) => { console.log('You clicked button ' + names[index]); }; return ( <View style={{ flex: 1,justifyContent: "center", alignItems: "center",}}> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"green", zIndex: 100, }} > <TouchableOpacity style={[{ height: 2*radius, width: 2*radius, borderRadius: radius, justifyContent: "center", alignItems: "center" }, { top:"30%",backgroundColor: `${colors[0]}` }]} //top:"30%", right:"1%", onPress={() => onButtonPress(0)} > <Text style={{ fontSize: textSize, color: "white", fontWeight: "700" }}>{names[0]}</Text> </TouchableOpacity> </View> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"gold", }} > <TouchableOpacity style={[{ height: 2*radius, width: 2*radius, borderRadius: radius, justifyContent: "center", alignItems: "center" }, { top: "50%", right:"20%", backgroundColor: `${colors[1]}` }]} //top:"2%", left:"10%", onPress={() => onButtonPress(1)} > <Text style={{ fontSize: textSize, color: "white", fontWeight: "700" }}>{names[1]}</Text> </TouchableOpacity> </View> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"blue", }} > <TouchableOpacity style={[{ height: 2*radius, width: 2*radius, borderRadius: radius, justifyContent: "center", alignItems: "center" }, { bottom:"50%", left:"20%", backgroundColor: `${colors[2]}` }]} //bottom:"2%", onPress={() => onButtonPress(2)} > <Text style={{ fontSize: textSize, color: "white", fontWeight: "700" }}>{names[2]}</Text> </TouchableOpacity> </View> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"red", }} > <TouchableOpacity style={[{ height: 2*radius, width: 2*radius, borderRadius: radius, justifyContent: "center", alignItems: "center" }, { bottom:"30%", backgroundColor: `${colors[3]}` }]} //bottom:"30%", left:"1%", onPress={() => onButtonPress(3)} > <Text style={{ fontSize: textSize, color: "white", fontWeight: "700" }}>{names[3]}</Text> </TouchableOpacity> </View> </View> ); }
/**
 * ButtonPad
 */

type ButtonPadProps = {
  radius?: number;
  names?: Array<string>;
  colors?: Array<string>;
  onClick?:(evt: ButtonPadEvent) => void;
};

export const ButtonPad = (props : ButtonPadProps)  =>  {
  const { onClick, radius = 45, names= ['X','Y','A','B'], colors = ["royalblue","limegreen","red","orange"] } = props;
  let textSize = radius;

  const onButtonPress = (index:number) => {
    console.log('You clicked button ' + names[index]);
  };
  

 
    return (

          <View style={{ flex: 1,justifyContent: "center", alignItems: "center",}}>
              <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"green",
                  zIndex: 100,
                }}
              >
                <TouchableOpacity
                  style={[{
                    height: 2*radius,
                    width: 2*radius,
                    borderRadius: radius,
                    justifyContent: "center",
                    alignItems: "center"
                  }, {  top:"30%",backgroundColor: `${colors[0]}` }]} //top:"30%", right:"1%", 
                  onPress={() => onButtonPress(0)}
                >
                  <Text style={{
                            fontSize: textSize,
                            color: "white",
                            fontWeight: "700"
                          }}>{names[0]}</Text>
                </TouchableOpacity>
              </View>

              <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"gold",
                }}
              >
                <TouchableOpacity
                  style={[{
                    height: 2*radius,
                    width: 2*radius,
                    borderRadius: radius,
                    justifyContent: "center",
                    alignItems: "center"
                  }, { top: "50%", right:"20%", backgroundColor: `${colors[1]}` }]} //top:"2%", left:"10%",
                  onPress={() => onButtonPress(1)}
                >
                  <Text style={{
                            fontSize: textSize,
                            color: "white",
                            fontWeight: "700"
                          }}>{names[1]}</Text>
                </TouchableOpacity>
              </View>

              <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"blue",
                }}
              >
                <TouchableOpacity
                  style={[{
                    height: 2*radius,
                    width: 2*radius,
                    borderRadius: radius,
                    justifyContent: "center",
                    alignItems: "center"
                  }, { bottom:"50%", left:"20%", backgroundColor: `${colors[2]}` }]} //bottom:"2%", 
                  onPress={() => onButtonPress(2)}
                >
                  <Text style={{
                            fontSize: textSize,
                            color: "white",
                            fontWeight: "700"
                          }}>{names[2]}</Text>
                </TouchableOpacity>
              </View>


            <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"red",
                }}
              >
                <TouchableOpacity
                  style={[{
                    height: 2*radius,
                    width: 2*radius,
                    borderRadius: radius,
                    justifyContent: "center",
                    alignItems: "center"
                  }, { bottom:"30%", backgroundColor: `${colors[3]}` }]} //bottom:"30%", left:"1%",
                  onPress={() => onButtonPress(3)}
                >
                  <Text style={{
                            fontSize: textSize,
                            color: "white",
                            fontWeight: "700"
                          }}>{names[3]}</Text>
                </TouchableOpacity>
              </View>

          </View>
    );
}

Pasar datos del componente a la aplicación

Para devolver datos a la aplicación principal, utilizamos una interfaz que contiene los estados de los botones y el nombre del botón pulsado

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
interface ButtonPadEvent {
states : Array<boolean>;
pressed: string;
}
interface ButtonPadEvent { states : Array<boolean>; pressed: string; }
interface ButtonPadEvent {
  states : Array<boolean>;
  pressed: string;
}

Modificamos la función onButtonPress para alimentar los estados y enviarlos a la función onClick.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const onButtonPress = (index:number) => {
let btnStates= [false,false,false,false];
btnStates[index] = true;
if(typeof(onClick)==="function"){
onClick({
states: btnStates,
pressed: names[index]
});
}
};
const onButtonPress = (index:number) => { let btnStates= [false,false,false,false]; btnStates[index] = true; if(typeof(onClick)==="function"){ onClick({ states: btnStates, pressed: names[index] }); } };
  const onButtonPress = (index:number) => {

    let btnStates= [false,false,false,false];
    btnStates[index] = true;

    if(typeof(onClick)==="function"){
      onClick({
             states: btnStates,
             pressed: names[index]
         });
       }
  };

N.B.: La notación if(typeof(onClick)===»function»){ onClick() } es equivalente a onClick && onClick()

Ahora podemos llamar a nuestro componente en la aplicación principal, crear una función de escucha y modificar sus parámetros.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const GamePad = () => {
const onPadClick = (data: any) => {
console.log("form ButtonPad: ",data);
}
return (
<View style={styles.mainBody}>
<Text
style={styles.mainTitle}>
AC Controller
</Text>
<ButtonPad radius={60} names={['\u2573', '\u25EF', '\u25B3', "\u25A2"]} colors={['black', 'black', 'black', 'black']} onClick={onPadClick} />
</View>
);
}
export default GamePad;
const GamePad = () => { const onPadClick = (data: any) => { console.log("form ButtonPad: ",data); } return ( <View style={styles.mainBody}> <Text style={styles.mainTitle}> AC Controller </Text> <ButtonPad radius={60} names={['\u2573', '\u25EF', '\u25B3', "\u25A2"]} colors={['black', 'black', 'black', 'black']} onClick={onPadClick} /> </View> ); } export default GamePad;
const GamePad = () =>  {
  const onPadClick = (data: any) => {
    console.log("form ButtonPad: ",data);
  }
    return (
      <View style={styles.mainBody}>
          <Text
            style={styles.mainTitle}>
            AC Controller
          </Text>
          <ButtonPad radius={60} names={['\u2573', '\u25EF', '\u25B3', "\u25A2"]} colors={['black', 'black', 'black', 'black']} onClick={onPadClick} />
      </View>            

    );
}
export default GamePad;
react-native-playpad Creación de un componente funcional con React Native
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
info Reloading app...
BUNDLE ./index.js
LOG Running "CustomApp" with {"rootTag":81}
LOG form ButtonPad: {"pressed": "╳", "states": [true, false, false, false]}
LOG form ButtonPad: {"pressed": "△", "states": [false, false, true, false]}
LOG form ButtonPad: {"pressed": "▢", "states": [false, false, false, true]}
LOG form ButtonPad: {"pressed": "◯", "states": [false, true, false, false]}
info Reloading app... BUNDLE ./index.js LOG Running "CustomApp" with {"rootTag":81} LOG form ButtonPad: {"pressed": "╳", "states": [true, false, false, false]} LOG form ButtonPad: {"pressed": "△", "states": [false, false, true, false]} LOG form ButtonPad: {"pressed": "▢", "states": [false, false, false, true]} LOG form ButtonPad: {"pressed": "◯", "states": [false, true, false, false]}
info Reloading app...
 BUNDLE  ./index.js

 LOG  Running "CustomApp" with {"rootTag":81}
 LOG  form ButtonPad:  {"pressed": "╳", "states": [true, false, false, false]}
 LOG  form ButtonPad:  {"pressed": "△", "states": [false, false, true, false]}
 LOG  form ButtonPad:  {"pressed": "▢", "states": [false, false, false, true]}
 LOG  form ButtonPad:  {"pressed": "◯", "states": [false, true, false, false]}

N.B.: para hacer las cosas correctamente, tendrías que crear los observadores onPressIn y onPressOut para poner los estados a cero y modificar la lógica para escuchar varios botones a la vez.

Código completo

./src/ACJoysticks.tsx

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/**
* ButtonPad
*/
interface ButtonPadEvent {
states : Array<boolean>;
pressed: string;
}
type ButtonPadProps = {
radius?: number;
names?: Array<string>;
colors?: Array<string>;
onClick?:(evt: ButtonPadEvent) => void;
};
export const ButtonPad = (props : ButtonPadProps) => {
const { onClick, radius = 45, names= ['X','Y','A','B'], colors = ["royalblue","limegreen","red","orange"] } = props;
let textSize = radius;
let btnStates= [false,false,false,false];
const onButtonPress = (index:number) => {
btnStates[index] = true;
if(typeof(onClick)==="function"){
onClick({
states: btnStates,
pressed: names[index]
});
}
};
const onButtonRel = (index:number) => {
btnStates[index] = false;
if(typeof(onClick)==="function"){
onClick({
states: btnStates,
pressed: names[index]
});
}
};
return (
<View style={{ flex: 1,justifyContent: "center", alignItems: "center",}}>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"green",
zIndex: 100,
}}
>
<TouchableOpacity
style={[{
height: 2*radius,
width: 2*radius,
borderRadius: radius,
justifyContent: "center",
alignItems: "center"
}, { top:"30%",backgroundColor: `${colors[0]}` }]} //top:"30%", right:"1%",
//onPress={() => onButtonPress(0)}
onPressIn={() => onButtonPress(0)}
onPressOut={() => onButtonRel(0)}
>
<Text style={{
fontSize: textSize,
color: "white",
fontWeight: "700"
}}>{names[0]}</Text>
</TouchableOpacity>
</View>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"gold",
}}
>
<TouchableOpacity
style={[{
height: 2*radius,
width: 2*radius,
borderRadius: radius,
justifyContent: "center",
alignItems: "center"
}, { top: "50%", right:"20%", backgroundColor: `${colors[1]}` }]} //top:"2%", left:"10%",
//onPress={() => onButtonPress(1)}
onPressIn={() => onButtonPress(1)}
onPressOut={() => onButtonRel(1)}
>
<Text style={{
fontSize: textSize,
color: "white",
fontWeight: "700"
}}>{names[1]}</Text>
</TouchableOpacity>
</View>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"blue",
}}
>
<TouchableOpacity
style={[{
height: 2*radius,
width: 2*radius,
borderRadius: radius,
justifyContent: "center",
alignItems: "center"
}, { bottom:"50%", left:"20%", backgroundColor: `${colors[2]}` }]} //bottom:"2%",
//onPress={() => onButtonPress(2)}
onPressIn={() => onButtonPress(2)}
onPressOut={() => onButtonRel(2)}
>
<Text style={{
fontSize: textSize,
color: "white",
fontWeight: "700"
}}>{names[2]}</Text>
</TouchableOpacity>
</View>
<View
style={{
//flex: 1,
justifyContent: "center",
alignItems: "center",
//backgroundColor:"red",
}}
>
<TouchableOpacity
style={[{
height: 2*radius,
width: 2*radius,
borderRadius: radius,
justifyContent: "center",
alignItems: "center"
}, { bottom:"30%", backgroundColor: `${colors[3]}` }]} //bottom:"30%", left:"1%",
//onPress={() => onButtonPress(3)}
onPressIn={() => onButtonPress(3)}
onPressOut={() => onButtonRel(3)}
>
<Text style={{
fontSize: textSize,
color: "white",
fontWeight: "700"
}}>{names[3]}</Text>
</TouchableOpacity>
</View>
</View>
);
}
/** * ButtonPad */ interface ButtonPadEvent { states : Array<boolean>; pressed: string; } type ButtonPadProps = { radius?: number; names?: Array<string>; colors?: Array<string>; onClick?:(evt: ButtonPadEvent) => void; }; export const ButtonPad = (props : ButtonPadProps) => { const { onClick, radius = 45, names= ['X','Y','A','B'], colors = ["royalblue","limegreen","red","orange"] } = props; let textSize = radius; let btnStates= [false,false,false,false]; const onButtonPress = (index:number) => { btnStates[index] = true; if(typeof(onClick)==="function"){ onClick({ states: btnStates, pressed: names[index] }); } }; const onButtonRel = (index:number) => { btnStates[index] = false; if(typeof(onClick)==="function"){ onClick({ states: btnStates, pressed: names[index] }); } }; return ( <View style={{ flex: 1,justifyContent: "center", alignItems: "center",}}> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"green", zIndex: 100, }} > <TouchableOpacity style={[{ height: 2*radius, width: 2*radius, borderRadius: radius, justifyContent: "center", alignItems: "center" }, { top:"30%",backgroundColor: `${colors[0]}` }]} //top:"30%", right:"1%", //onPress={() => onButtonPress(0)} onPressIn={() => onButtonPress(0)} onPressOut={() => onButtonRel(0)} > <Text style={{ fontSize: textSize, color: "white", fontWeight: "700" }}>{names[0]}</Text> </TouchableOpacity> </View> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"gold", }} > <TouchableOpacity style={[{ height: 2*radius, width: 2*radius, borderRadius: radius, justifyContent: "center", alignItems: "center" }, { top: "50%", right:"20%", backgroundColor: `${colors[1]}` }]} //top:"2%", left:"10%", //onPress={() => onButtonPress(1)} onPressIn={() => onButtonPress(1)} onPressOut={() => onButtonRel(1)} > <Text style={{ fontSize: textSize, color: "white", fontWeight: "700" }}>{names[1]}</Text> </TouchableOpacity> </View> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"blue", }} > <TouchableOpacity style={[{ height: 2*radius, width: 2*radius, borderRadius: radius, justifyContent: "center", alignItems: "center" }, { bottom:"50%", left:"20%", backgroundColor: `${colors[2]}` }]} //bottom:"2%", //onPress={() => onButtonPress(2)} onPressIn={() => onButtonPress(2)} onPressOut={() => onButtonRel(2)} > <Text style={{ fontSize: textSize, color: "white", fontWeight: "700" }}>{names[2]}</Text> </TouchableOpacity> </View> <View style={{ //flex: 1, justifyContent: "center", alignItems: "center", //backgroundColor:"red", }} > <TouchableOpacity style={[{ height: 2*radius, width: 2*radius, borderRadius: radius, justifyContent: "center", alignItems: "center" }, { bottom:"30%", backgroundColor: `${colors[3]}` }]} //bottom:"30%", left:"1%", //onPress={() => onButtonPress(3)} onPressIn={() => onButtonPress(3)} onPressOut={() => onButtonRel(3)} > <Text style={{ fontSize: textSize, color: "white", fontWeight: "700" }}>{names[3]}</Text> </TouchableOpacity> </View> </View> ); }
/**
 * ButtonPad
 */

interface ButtonPadEvent {
  states : Array<boolean>;
  pressed: string;
}

type ButtonPadProps = {
  radius?: number;
  names?: Array<string>;
  colors?: Array<string>;
  onClick?:(evt: ButtonPadEvent) => void;
};



export const ButtonPad = (props : ButtonPadProps)  =>  {
  const { onClick, radius = 45, names= ['X','Y','A','B'], colors = ["royalblue","limegreen","red","orange"] } = props;
  let textSize = radius;
  let btnStates= [false,false,false,false];

  const onButtonPress = (index:number) => {
    btnStates[index] = true;

    if(typeof(onClick)==="function"){
      onClick({
             states: btnStates,
             pressed: names[index]
         });
       }
  };
  
  const onButtonRel = (index:number) => {
    btnStates[index] = false;
    
    if(typeof(onClick)==="function"){
      onClick({
             states: btnStates,
             pressed: names[index]
         });
       }
  };
  
    return (

          <View style={{ flex: 1,justifyContent: "center", alignItems: "center",}}>
              <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"green",
                  zIndex: 100,
                }}
              >
                <TouchableOpacity
                  style={[{
                    height: 2*radius,
                    width: 2*radius,
                    borderRadius: radius,
                    justifyContent: "center",
                    alignItems: "center"
                  }, {  top:"30%",backgroundColor: `${colors[0]}` }]} //top:"30%", right:"1%", 
                  //onPress={() => onButtonPress(0)}
                  onPressIn={() => onButtonPress(0)}
                  onPressOut={() => onButtonRel(0)}
                >
                  <Text style={{
                            fontSize: textSize,
                            color: "white",
                            fontWeight: "700"
                          }}>{names[0]}</Text>
                </TouchableOpacity>
              </View>

              <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"gold",
                }}
              >
                <TouchableOpacity
                  style={[{
                    height: 2*radius,
                    width: 2*radius,
                    borderRadius: radius,
                    justifyContent: "center",
                    alignItems: "center"
                  }, { top: "50%", right:"20%", backgroundColor: `${colors[1]}` }]} //top:"2%", left:"10%",
                  //onPress={() => onButtonPress(1)}
                  onPressIn={() => onButtonPress(1)}
                  onPressOut={() => onButtonRel(1)}
                >
                  <Text style={{
                            fontSize: textSize,
                            color: "white",
                            fontWeight: "700"
                          }}>{names[1]}</Text>
                </TouchableOpacity>
              </View>

              <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"blue",
                }}
              >
                <TouchableOpacity
                  style={[{
                    height: 2*radius,
                    width: 2*radius,
                    borderRadius: radius,
                    justifyContent: "center",
                    alignItems: "center"
                  }, { bottom:"50%", left:"20%", backgroundColor: `${colors[2]}` }]} //bottom:"2%", 
                  //onPress={() => onButtonPress(2)}
                  onPressIn={() => onButtonPress(2)}
                  onPressOut={() => onButtonRel(2)}
                >
                  <Text style={{
                            fontSize: textSize,
                            color: "white",
                            fontWeight: "700"
                          }}>{names[2]}</Text>
                </TouchableOpacity>
              </View>


            <View
                style={{
                  //flex: 1,
                  justifyContent: "center",
                  alignItems: "center",
                  //backgroundColor:"red",
                }}
              >
                <TouchableOpacity
                  style={[{
                    height: 2*radius,
                    width: 2*radius,
                    borderRadius: radius,
                    justifyContent: "center",
                    alignItems: "center"
                  }, { bottom:"30%", backgroundColor: `${colors[3]}` }]} //bottom:"30%", left:"1%",
                  //onPress={() => onButtonPress(3)}
                  onPressIn={() => onButtonPress(3)}
                  onPressOut={() => onButtonRel(3)}
                >
                  <Text style={{
                            fontSize: textSize,
                            color: "white",
                            fontWeight: "700"
                          }}>{names[3]}</Text>
                </TouchableOpacity>
              </View>

          </View>
    );
}

./App.tsx

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import {ButtonPad} from "./src/ACJoysticks";
const GamePad = () => {
const onPadClick = (data: any) => {
console.log("from ButtonPad: ",data);
//data.states[0], data.pressed
}
return (
<View style={styles.mainBody}>
<Text
style={styles.mainTitle}>
AC Controller
</Text>
<ButtonPad radius={60} names={[ '\u25B3', '\u25A2', '\u25EF', '\u2573',]} colors={['black', 'black', 'black', 'black']} onClick={onPadClick} />
</View>
);
}
export default GamePad;
//parameters
let BACKGROUND_COLOR = "#161616"; //191A19
let BUTTON_COLOR = "#346751"; //1E5128
let ERROR_COLOR = "#C84B31"; //4E9F3D
let TEXT_COLOR = "#ECDBBA"; //D8E9A8
const styles = StyleSheet.create({
mainBody: {
flex:1,
justifyContent: 'center',
alignItems: "center",
color:TEXT_COLOR,
backgroundColor: BACKGROUND_COLOR,
},
mainTitle:{
color: TEXT_COLOR,
fontSize: 30,
textAlign: 'center',
borderBottomWidth: 2,
borderBottomColor: ERROR_COLOR,
width:"100%"
},
});
import React from "react"; import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; import {ButtonPad} from "./src/ACJoysticks"; const GamePad = () => { const onPadClick = (data: any) => { console.log("from ButtonPad: ",data); //data.states[0], data.pressed } return ( <View style={styles.mainBody}> <Text style={styles.mainTitle}> AC Controller </Text> <ButtonPad radius={60} names={[ '\u25B3', '\u25A2', '\u25EF', '\u2573',]} colors={['black', 'black', 'black', 'black']} onClick={onPadClick} /> </View> ); } export default GamePad; //parameters let BACKGROUND_COLOR = "#161616"; //191A19 let BUTTON_COLOR = "#346751"; //1E5128 let ERROR_COLOR = "#C84B31"; //4E9F3D let TEXT_COLOR = "#ECDBBA"; //D8E9A8 const styles = StyleSheet.create({ mainBody: { flex:1, justifyContent: 'center', alignItems: "center", color:TEXT_COLOR, backgroundColor: BACKGROUND_COLOR, }, mainTitle:{ color: TEXT_COLOR, fontSize: 30, textAlign: 'center', borderBottomWidth: 2, borderBottomColor: ERROR_COLOR, width:"100%" }, });
import React from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import {ButtonPad} from "./src/ACJoysticks";

const GamePad = () =>  {
  const onPadClick = (data: any) => {
    console.log("from ButtonPad: ",data);
    //data.states[0], data.pressed
  }

    return (
      <View style={styles.mainBody}>
          <Text
            style={styles.mainTitle}>
            AC Controller
          </Text>
          <ButtonPad radius={60} names={[ '\u25B3', '\u25A2', '\u25EF',  '\u2573',]} colors={['black', 'black', 'black', 'black']} onClick={onPadClick} />
      </View>            

    );
}
export default GamePad;

//parameters
let BACKGROUND_COLOR = "#161616"; //191A19
let BUTTON_COLOR = "#346751"; //1E5128
let ERROR_COLOR = "#C84B31"; //4E9F3D
let TEXT_COLOR = "#ECDBBA"; //D8E9A8

const styles = StyleSheet.create({

  mainBody: {
    flex:1,
    justifyContent: 'center',
    alignItems: "center",
    color:TEXT_COLOR,
    backgroundColor: BACKGROUND_COLOR,
  },

  mainTitle:{
    color: TEXT_COLOR,
    fontSize: 30,
    textAlign: 'center',
    borderBottomWidth: 2,
    borderBottomColor: ERROR_COLOR,
    width:"100%"
  },
});

Aplicaciones

  • Cree componentes reutilizables y configurables para sus aplicaciones
  • Cree aplicaciones para controlar sus proyectos mediante Bluetooth, BLE o Wifi

Fuentes