React Native ListView for Highscore in a game, how to highlight a speficic row

391
June 27, 2017, at 03:10 AM

Im trying to program a Highscore-Screen for a Quiz-Game with a ListView which gives me all the players with their scores. Actually I want to highlight my points, because in the ListView are no nicknames, just ID and points from every Player. The Highscore.js Screen has a connection to a websocket which send me a JSON like this :

    {"Finish":"true","Scores":{"48046":0,"48056":2}}

In this JSON you see if the Game is finished, and then the always changing ID and score for a Player. Here are two Player, Player 46046 has 0 Points and Player 486056 has 2 Points. I don't know which one is my ID, because the websocket server generates the ID. Only by comparing my points to this JSON-Message I get to know my ID. Here is the ListView which I have:

    <ListView
                dataSource={
                    this.ds.cloneWithRows(
                        this.state.sortable
                    )
                }
                renderRow={(rowData)=> {
                    return (
                        <View style={styles.row}>
                            <Text style={styles.rowText}> Spieler: {rowData.toString().substring(0,6)}</Text><Text style={styles.scoreText}>  Score: {rowData.toString().substring(6,7)}</Text>
                        </View>
                    )
                }}
            />

I didn't know how to get access to the ID and the Value in the rowData correctly. When I wrote just rowData it gave me the ID and Score attached, so "48046":0 became 480460, that's why I used substring. If you can teach me a better method, please tell me!

The next and most important thing is, that I don't know to get the row selected and highlighted which is me. I know my score, but how can I generally highlight my row? For example if I have 2 points I'm the player 48056. I integrated a counter which I put into my WebsocketController, it's just a variable which counts my point and it is accessable from every component. The Websocket-Server generates for every game a new ID for every Player. How can I highlight me? It would be enough for me just to change the backgroundColor from my row.

Here is my code:

    import React, {Component} from 'react';
    import {  View, Text, ListView, StyleSheet, KeyboardAvoidingView, Image,                 TouchableOpacity } from 'react-native';
    import WebsocketController from './WebsocketController';

    class HighScore extends Component {
        constructor(props) {
            super(props);
            this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
            this.state =({
                sortable : [],
            })
        }
        async onButtonPressed() {
            console.log("HighScore ButtonPressed");
            var newGame = new WebsocketController();
            this.props.navigation.navigate('StartGame');
        }
        static navigationOptions = {
            header: null
        };
        componentWillMount(){
            const {params} = this.props.navigation.state;
            console.log("params",params.Scores);
            for (var id in params.Scores){
                this.setState= ({
                    sortable : this.state.sortable.push([id, params.Scores[id]])
                })
            }
            this.state.sortable.sort(function(a,b){ 
                return b[1]-a[1];
            });
            for (var i = 0 ; i <this.state.sortable.length; i++){
                console.log(this.state.sortable[i]);
            }
        }
        render() {
           var wsc = new WebsocketController();
            wsc.close();
            return(
            <KeyboardAvoidingView style = {styles.container}
                        behaviour=" padding"
            >
                <View style = {styles.logoContainer}>
                    <Image
                        style={styles.logo}
                        source={require('../../images/Breezeicons-actions-22-games-highscores.svg.png')} //Logo for QuizGame
                    />
                </View>
                <View style = {styles.listContainer}>
                    <ListView
                        dataSource={
                            this.ds.cloneWithRows(
                                this.state.sortable
                            )}
                        renderRow={(rowData)=> {
                            return (
                                <View style={styles.row}>
                                    <Text style={styles.rowText}> Spieler: {rowData.toString().substring(0,6)}</Text><Text style={styles.scoreText}>  Score: {rowData.toString().substring(6,7)}</Text>
                                </View>
                            )
                        }}
                    />
                </View>
                <View style = {styles.listContainer}>
                    <Text style={styles.yourScoreText}> Your score is {wsc.getPoints()} ! </Text>
                </View>
                <View style={styles.buttonContainer}>
                    <TouchableOpacity style = {styles.buttonContainer}
                        onPress = {this.onButtonPressed.bind(this)}
                    >
                    <Text style = {styles.buttonText}> Start new Game </Text>
                    </TouchableOpacity>
                </View>
            </KeyboardAvoidingView>
            );
        }
    }
    var styles = StyleSheet.create({
        container: {
            justifyContent: 'flex-start',
            alignItems: 'center', 
            backgroundColor: '#daa520', 
            flex:1,
        },
        heading:{
            color: '#800000', 
            width: 300, 
            textAlign: 'center',
            justifyContent:'center',
            padding:10,
            fontSize:28,
            flex:1,
            fontFamily:'verdana'
        },
        logoContainer: {
            justifyContent: 'flex-start', 
            alignItems: 'center', 
            backgroundColor: '#daa520', 
            flex:1,
            width:  880,
            height: 440,
        },
        buttonContainer:{
            backgroundColor: '#800000',
            marginBottom: 20,
            width: 340,
            height: 50,
        },
        buttonText: {
            textAlign: 'center',
            textAlignVertical: 'center',
            color:'#FFF',
            fontWeight: '800',
            marginTop: 18,
        },
        logo: {
            width:  880, 
            height: 440, 
            resizeMode: 'contain',
            marginTop: 5,
            flex: 1,
        },
        row: {
            flexDirection:'row',
            justifyContent: 'center',
            padding: 10,
            marginBottom:3,
            backgroundColor: '#f4f4f4',
        },
        scoreText:{
            textAlign: 'left',
            textAlignVertical: 'center',
            color: '#010001',
            fontWeight: '800',
            marginBottom: 1,
        },
        rowText: {
            textAlign: 'left',
            textAlignVertical: 'center',
            color: '#800000',
            fontWeight: '800',
            marginBottom: 1,
        },
        imageContainer: {
            flex: 1,
            width:  440, 
            height: 220,
            marginTop: 5
        },
        listContainer:{
            flex:1
        },
        titleStyle:{
            textAlign: 'left',
            textAlignVertical: 'center',
            color:'#FFF', 
            fontWeight: '900',
            marginBottom: 20,
            fontSize: 20,
        },
        yourScoreText: {
            textAlign: 'left',
            textAlignVertical: 'center',
            color: '#800000',
            fontWeight: '800',
            marginBottom: 1,
            fontSize: 35
        }
    });
        export default HighScore;

Thank you very much for any help!

Answer 1

You will need to pass the current player's id to the listview. Once you have the player id, you can conditionally set the style on the view returned by renderRow. For example, say the id is passed in this.props.playerId:

<View style={rowData.toString().substring(0,6) == this.props.playerId ? styles.row : styles.highlightedRow}>
    <Text style={styles.rowText}> Spieler: {rowData.toString().substring(0,6)}</Text><Text style={styles.scoreText}>  Score: {rowData.toString().substring(6,7)}</Text>
</View>

Of course this means you will have to define the styling for 'highlightedRow' in styles.

Rent Charter Buses Company
READ ALSO
Face detection on partial frame in Google Mobile Vision for Android

Face detection on partial frame in Google Mobile Vision for Android

Can anyone recommend an approach to specify a subset of a frame for face detection? This could be for a fixed area, say one quadrant of the frame, throughout the face tracking - so not dynamic per frameIn my case I only need to scan a fixed part of the frame and am interesting...

305
Processing url parameters in email viewer app

Processing url parameters in email viewer app

Small backstory, I am trying to send contacts of mine a email message that contains a link to my websiteI want to track if they are clicking the link I sent them

388
Layout like gmail inbox for zoom in and out in android using android studio

Layout like gmail inbox for zoom in and out in android using android studio

I am making an android app in which I have an fragment where I have a 2 relative layouts as a child of a linear layoutNow I want that on pinching the layout, 2nd relative layout which is below the first relative layout should have zooming effect like on pinch,...

398
Android O &amp; Gradle

Android O & Gradle

I'm trying to look into some weird notification things going on when I upgrade a device to Android OSo I updated my build

606