اذهب إلى المحتوى

السؤال

نشر (معدل)

السلام عليكم .. أود ان أطبق هذا التصميم بفكرة ال Flatlist .. وهى التنقل بين الصور المختلفة باستخدام الاسهم وقد طبقتها بفضل الله فى احد مشاريعى السابقة .. ولكن الان اريد ان اخوض تجربة اصعب .. وهى عندما أضغط على احدى الصور بالاسفل فانها تظهر فوق فى الاعلى .. واتسائل هل هذا يتطلب منى ان اقوم بعمل 2 FlatList ام واحدة فقط  ؟؟؟ 

react_challenge_album_view.thumb.png.c9826b7efa12f47d583d826a70902a2d.png

 

أنا نجحت بفضل الله وبفضل المساهمين هنا فى عمل الجزء الاول وهو التنقل عن طريق هذا الكود فى الاسفل ..
ولكن المشكلة اريد ان احول ال Border الخاص بالصورة فى الاسفل الى اللون الازرق عندما احرك الاسهم فوق .. وايضا اذا ضغطت على اى صورة فى الاسفل يتحول ال Border الخاص بها الى اللون الازرق وتظهر هى الاخرى بالاعلى .. حاولت طرق كثيرة وفشلت فى التوفيق بينهم .. تحويل لون ال Border للون الازرق سهل جدا بفضل الله .. لكن الصعب هو عرض الصورة المضغوط عليها بالاعلى 


رجاء ماذا الذى يجب ان افعله فى هذا الكود ؟؟ وان كان هناك مصدر يمكننى مثلا repo على github فاتمنى تركه فى الاجابات .. 

import React, { useState, useRef, useEffect } from "react";
import { StyleSheet, View, FlatList, Dimensions, Text } from "react-native";
import { AntDesign } from "@expo/vector-icons";

const photos = [
  { id: 1, title: "Photo 1" },
  { id: 2, title: "Photo 2" },
  { id: 3, title: "Photo 3" },
  { id: 4, title: "Photo 4" },
  { id: 5, title: "Photo 5" },
  { id: 6, title: "Photo 6" },
];

const phoneWidth = Dimensions.get("screen").width;
const phoneHeight = Dimensions.get("screen").height;

function ScrollScreen() {
  const [index, setIndex] = useState(0);
  const refContainer = useRef();

  useEffect(() => {
    refContainer.current.scrollToIndex({ animated: true, index }); // تغيير على حسب قيمة ستايت
  }, [index]);

  const theNext = () => {
    if (index < photos.length - 1) {
      setIndex(index + 1);
    }
  };
  const thePrevious = () => {
    if (index > 0) {
      setIndex(index - 1);
    }
  };

  return (
    <View style={styles.con}>
      <AntDesign
        style={[styles.iconConPosition, { left: phoneWidth * 0.05 }]}
        onPress={thePrevious}
        size={55}
        color="#0dddcb"
        name="caretleft"
      />

      <AntDesign
        style={[styles.iconConPosition, { right: phoneWidth * 0.05 }]}
        onPress={theNext}
        size={55}
        color="#0dddcb"
        name="caretright"
      />
      <FlatList
        ref={refContainer}
        data={photos}
        keyExtractor={(item, index) => item.id.toString()}
        style={styles.flatList}
        renderItem={({ item, index }) => (
          <View
            style={{
              height: 150,
              width: phoneWidth * 0.7,
              margin: 50,
              backgroundColor: "red",
              alignSelf: "center",
              justifyContent: "center",
              alignItems: "center",
            }}
          >
            <Text>{item.id}</Text>
            <Text>{item.title}</Text>
          </View>
        )}
        horizontal
        pagingEnabled //تفعيل خاصية التمرير
        showsHorizontalScrollIndicator={false} // محدد التمرير
        initialScrollIndex={index}
      />
      <FlatList
        data={photos}
        keyExtractor={(item, index) => item.id.toString()}
        style={styles.flatList}
        renderItem={({ item, index }) => (
          <View
            style={{
              height: 100,
              width: phoneWidth * 0.4,
              margin: 7,
              backgroundColor: "red",
              alignSelf: "center",
              justifyContent: "center",
              alignItems: "center",
            }}
          >
            <Text>{item.id}</Text>
            <Text>{item.title}</Text>
          </View>
        )}
        horizontal
      />
    </View>
  );
}

const styles = StyleSheet.create({
  con: {
    flex: 1,
    alignItems: "center",
    backgroundColor: "#fae7ec",
    paddingBottom: 100,
  },
  flatList: {
    flex: 1,
    marginVertical: phoneHeight * 0.05,
  },
  iconConPosition: {
    position: "absolute",
    top: phoneHeight * 0.24,
    zIndex: 1,
  },
});
export default ScrollScreen;


وشكرا مقدما 

تم التعديل في بواسطة Ahmed Sawy
خطأ املائى

Recommended Posts

  • 1
نشر

مرحباً أحمد: 
يجب أن أقوم بالإطلاع على المشروع لإفادتك بشكل أدق ولكن سأقول لك الفكرة بشكل عام

  1. في البداية لديك صفحة وبداخلها مكونين (.ال slider + العناصر المربعة )
    function App() {
      return (
        <View style={styles.con}>
          <Slider />
    
          <Boxes />
    
        </View>
      );
    }

     

  2. المكونين يتشاركون في البيانات كما تفعل في المثال المطروح 
    const photos = [
      { id: 1, title: "Photo 1" },
      { id: 2, title: "Photo 2" },
      { id: 3, title: "Photo 3" },
      { id: 4, title: "Photo 4" },
      { id: 5, title: "Photo 5" },
      { id: 6, title: "Photo 6" },
    ];

     

  3. الصفحة التي تجمعهم فيها state عبارة عن selectedImg وستبدأ من ال 1 ( على افتراض أن لديك صورة لها id=1 بالطبع يمكنك تغييرها ) + دالة لتغيير هذه القيمة في حالتين فقط ( عند الضغط على أي مربع أو التحريك في ال slider ) + قمنا بتمرير الدالة للمكونين كما ذكرت في النقطة السابقة أم عن تمرير selectedImg فهو ما ستحتاج لكي تجعل الصورتين متطابقتين في الأبناء  
    function App() {
      const [ selectedImg, setSelectedImg ] = useState(1);
    
      updateSelectedImg = imgId => {
    	setSelectedImg(imgId);
      }
    
      return (
        <View style={styles.con}>
          <Slider selectedImg={selectedImg} updateSelectedImg={updateSelectedImg} />
    
          <Boxes selectedImg={selectedImg} updateSelectedImg={updateSelectedImg} />
    
        </View>
      );
    }

     

  4. بداخل كل مكون سواء Slider أو Box عند تغيير القيمة يجب أن تكلم الخاصية updateSelectedImg لكي تقوم بتحديث القيمة selectedImg ويقوم المكون الآخر باستخدامها فمثلاً عند الضغط علي المكون Box سيحدث الآتي: 
     

    function Boxes(props) {
      const { selectedImg, updateSelectedImg } = props;
      const [ activeImgId, setActiveImgId ] = useState(1);
    
      
      useEffect(() => {
        // عندما يتغير الid
        // سواء من هذا المكون أو من غيره نقوم بتحديث ال state 
        // ونقوم باستخدامها في ال render
        if(selectedImg !== activeImgId)  {
        	setActiveImgId(selectedImg);
        }
      
      }, [selectedImg]);
      
      hangleBoxClick = item => {
      // تحديث الأب ليستفاد المكون الآخر بالتحديث
        updateSelectedImg(item.id);
      }
      
      return(
      	// Loop through boxes [ FlatList ]
        // يمكنك استخدام activeImgId 
    // في عمل ما تريد
         <FlatList
            data={photos}
            keyExtractor={(item, index) => item.id.toString()}
            style={styles.flatList}
            renderItem={({ item, index }) => (
              <TouchableHighlight onPress={hangleBoxClick(item)}>
                  <View style={styles.container}>
                   	<Text>{item.id}</Text>
                	<Text>{item.title}</Text>
                  </View>
              </TouchableHighlight>
            )}
         />
      )
    }

     

  5. وكذلك بالنسبة للمكون الآخر 

  • 0
نشر
بتاريخ 2 ساعات قال Mohammed Saber:

مرحباً أحمد: 
يجب أن أقوم بالإطلاع على المشروع لإفادتك بشكل أدق ولكن سأقول لك الفكرة بشكل عام

  1. في البداية لديك صفحة وبداخلها مكونين (.ال slider + العناصر المربعة )
    
    function App() {
      return (
        <View style={styles.con}>
          <Slider />
    
          <Boxes />
    
        </View>
      );
    }

     

  2. المكونين يتشاركون في البيانات كما تفعل في المثال المطروح 
    
    const photos = [
      { id: 1, title: "Photo 1" },
      { id: 2, title: "Photo 2" },
      { id: 3, title: "Photo 3" },
      { id: 4, title: "Photo 4" },
      { id: 5, title: "Photo 5" },
      { id: 6, title: "Photo 6" },
    ];

     

  3. الصفحة التي تجمعهم فيها state عبارة عن selectedImg وستبدأ من ال 1 ( على افتراض أن لديك صورة لها id=1 بالطبع يمكنك تغييرها ) + دالة لتغيير هذه القيمة في حالتين فقط ( عند الضغط على أي مربع أو التحريك في ال slider ) + قمنا بتمرير الدالة للمكونين كما ذكرت في النقطة السابقة أم عن تمرير selectedImg فهو ما ستحتاج لكي تجعل الصورتين متطابقتين في الأبناء  
    
    function App() {
      const [ selectedImg, setSelectedImg ] = useState(1);
    
      updateSelectedImg = imgId => {
    	setSelectedImg(imgId);
      }
    
      return (
        <View style={styles.con}>
          <Slider selectedImg={selectedImg} updateSelectedImg={updateSelectedImg} />
    
          <Boxes selectedImg={selectedImg} updateSelectedImg={updateSelectedImg} />
    
        </View>
      );
    }

     

  4. بداخل كل مكون سواء Slider أو Box عند تغيير القيمة يجب أن تكلم الخاصية updateSelectedImg لكي تقوم بتحديث القيمة selectedImg ويقوم المكون الآخر باستخدامها فمثلاً عند الضغط علي المكون Box سيحدث الآتي: 
     

    
    function Boxes(props) {
      const { selectedImg, updateSelectedImg } = props;
      const [ activeImgId, setActiveImgId ] = useState(1);
    
      
      useEffect(() => {
        // عندما يتغير الid
        // سواء من هذا المكون أو من غيره نقوم بتحديث ال state 
        // ونقوم باستخدامها في ال render
        if(selectedImg !== activeImgId)  {
        	setActiveImgId(selectedImg);
        }
      
      }, [selectedImg]);
      
      hangleBoxClick = item => {
      // تحديث الأب ليستفاد المكون الآخر بالتحديث
        updateSelectedImg(item.id);
      }
      
      render() {
      	// Loop through boxes [ FlatList ]
        // يمكنك استخدام activeImgId 
    // في عمل ما تريد
         <FlatList
            data={photos}
            keyExtractor={(item, index) => item.id.toString()}
            style={styles.flatList}
            renderItem={({ item, index }) => (
              <TouchableHighlight onPress={hangleBoxClick(item)}>
                  <View style={styles.container}>
                   	<Text>{item.id}</Text>
                	<Text>{item.title}</Text>
                  </View>
              </TouchableHighlight>
            )}
      }
    }

     

  5. وكذلك بالنسبة للمكون الآخر 

عذرا أخى انا جربت طريقتك لكن ظهرت لى بعض الاخطاء .. لاحظ انك دمجت الكلاس كمبوننت ب الفانكشنال كمبوننت

  • 0
نشر
بتاريخ 2 ساعات قال Ahmed Sawy:

عذرا أخى انا جربت طريقتك لكن ظهرت لى بعض الاخطاء .. لاحظ انك دمجت الكلاس كمبوننت ب الفانكشنال كمبوننت

مرحباً بك: 
لقد قمت بتصحيح الإجابة 
قم بفهم المبدأ وطبق بطريقتك الخاصة ليس عليك أن تستخدم نفس الطريقة المهم هو الفهم 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...